SQL chuyển đổi BLOB thành chuỗi

Tôi có rất nhiều bản ghi trong đó văn bản đã được lưu trữ trong một đốm màu trong MySQL. Để dễ xử lý, tôi muốn thay đổi định dạng trong cơ sở dữ liệu thành TEXT. Bất kỳ ý tưởng nào về cách dễ dàng thực hiện thay đổi để không làm gián đoạn dữ liệu - tôi đoán nó sẽ cần được mã hóa đúng cách?

 

Thủ thuật cơ sở dữ liệu Oracle của Donald Burleson28 tháng 9, 2015

Câu hỏi. Làm cách nào tôi có thể chuyển đổi BLOB thành varchar trong Oracle? . 06502 PL/SQL. lỗi số hoặc giá trị. chiều dài biến thô quá dài

Đây là truy vấn tôi đã thực hiện để chuyển đổi kiểu dữ liệu blob

CHỌN DISTINCT
TQ. TEST_CODE,
TQ. TEST_SORT,
UTL_RAW. CAST_TO_VARCHAR2[DBMS_LOB. SUBSTR[TEST_ALLOWEDB, 4000,1]] TEST_ALLOWEDB
FROM
TEST_QUESTION TQ
WHERE
. TQ. MÃ KIỂM TRA. ',']>0

Vui lòng đề xuất thêm ý tưởng để xử lý mã này để chuyển đổi Oracle BLOB thành trường ký tự vì các loại dữ liệu RAW của Oracle bị giới hạn ở 2000 byte.  

Câu trả lời. Chương trình sau chọn dữ liệu CLOB và đặt vào biến VARCHAR2

SQL> @kiểm tra. sql

TẠO HOẶC THAY THẾ THỦ TỤC TEST_PROC AS

SỐ CNT. = 1;
CLOB ĐỊNH VỊ;
GIÃ SỐ SỐ BẮT ĐẦU. =4000;
KẾT THÚC SỐ LƯỢNG. = 1;
CLOB_TEXT VARCHAR2[4000];
BEGIN

con trỏ c là
CHỌN THẺ
VÀO ĐỊNH VỊ
TỪ KIỂM TRA2
. ĐỌC [CLOB_TEXT];
open c;
LOOP
c = DBMS_LOB.READ [CLOB_TEXT];
DBMS_OUTPUT. PUT_LINE['GHI TAG = '. c];
END LOOP;
đóng c;

END;
/

THAY ĐỔI THỦ TỤC TEST_PROC COMPILE;
HIỂN THỊ LỖI;

ĐẶT ĐẦU RA MÁY CHỦ TRÊN KÍCH THƯỚC 1000000
THỰC HÀNH TEST_PROC;

Laurent Schneider [tác giả cuốn Lập trình Oracle SQL nâng cao] mô tả mã để chuyển đổi cột BLOB thành cột VARCHAR2

tiền đề là đơn giản. được cung cấp một cơ sở dữ liệu được cung cấp bởi, ví dụ, các công cụ RDBMS MySQL hoặc SQLite cực kỳ phổ biến không cung cấp biểu diễn “gốc” của UUID hoặc GUID, các nhà thiết kế cơ sở dữ liệu và lập trình viên hệ thống có quyền lựa chọn. bạn có lưu trữ GUID dưới dạng văn bản thuần túy [_______15 hoặc

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
6] và nhận điểm nhấn về hiệu suất, bộ nhớ và lưu trữ đi kèm với nó hay bạn tháo găng tay và khai thác loại cột
INSERT INTO mytable ['guid']
VALUES ["not a guid"]
7 trong DDL của mình?

Để biết một số ngữ cảnh nhanh về lý do tại sao câu hỏi hóc búa này tồn tại [và vui lòng bỏ qua đoạn này và đoạn tiếp theo nếu bạn đã hiểu biết về mã hóa]. bất cứ khi nào bạn thấy dữ liệu có dạng một chuỗi các ký tự thập lục phân, bạn có thể đặt cược số tiền thấp nhất của mình rằng đó chỉ là biểu diễn của dữ liệu cơ bản – chứ không phải bản thân dữ liệu – mà bạn đang xử lý. Là một ví dụ cụ thể và rất phù hợp, UUID phổ biến.

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
8

Những gì bạn đang thấy ở đây là một chuỗi các ký tự ascii. Nếu bạn đếm chúng, dấu ngoặc và dấu gạch ngang sang một bên, bạn sẽ thấy có 32 trong số chúng. 32 ký tự ascii chiếm 32 byte. Nhưng GUID hoặc UUID chỉ dài mười sáu byte – tại sao. ?

Quay lại vấn đề hiện tại. khi bạn yêu cầu cơ sở dữ liệu của mình lưu trữ UUID của chúng tôi từ trước trong trường

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
5 hoặc
INSERT INTO mytable ['guid']
VALUES ["not a guid"]
6, thì không có manh mối nào cho thấy bạn đang nói với cơ sở dữ liệu rằng nó có thể lấy 32 byte bạn cung cấp và thay vào đó chuyển chúng vào trường 16 byte. Hãy nghĩ về nó, làm thế nào nó có thể biết rằng sau khi bạn thực hiện truy vấn SQL,

INSERT INTO mytable ['guid']
VALUES ["4c36947a-f5ad-11e7-8f4c-7085c25fb679"]

rằng bạn sẽ không theo dõi điều đó với người khác

INSERT INTO mytable ['guid']
VALUES ["not a guid"]

Nó không thể. Bạn đã yêu cầu nó coi cột này là dữ liệu văn bản UTF8/ASCII và đó là những gì nó đang làm. Trên thực tế, truy vấn mà chúng tôi đã thực hiện ở trên sẽ không chỉ chiếm 32 byte, vì đối với cơ sở dữ liệu,

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
2 trong GUID là một phần không thể thiếu của giá trị cột và không thể bỏ đi rồi chèn lại. . Vì vậy, nó tuân thủ nghiêm ngặt và lưu trữ GUID 16 byte của bạn dưới dạng giá trị khổng lồ 32, 36 hoặc thậm chí 38 byte [với dấu ngoặc nhọn mở và đóng và dấu gạch ngang phân chia], chiếm 238% dung lượng mà nó thực sự cần

Vì vậy, các nhà phát triển lành mạnh lưu trữ GUID của họ trong các cột

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
7, dưới dạng các giá trị 16 byte cố định. Khi chạy, trình điều khiển/bộ điều hợp/trình bao bọc cơ sở dữ liệu sau đó chuyển đổi giá trị đã lưu từ một mảng 16 byte thành bất kỳ kiểu dữ liệu nào mà phần mềm sử dụng để biểu thị GUID và phần còn lại, như họ nói, là lịch sử

Nhưng điều gì sẽ xảy ra khi bạn cần tìm hiểu thủ công cơ sở dữ liệu của mình và tìm kiếm thứ gì đó?

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
4? . Đó là GUID của chúng tôi được biểu thị dưới dạng UTF-8 và các biểu tượng mặt cười sang một bên, nó không đẹp. Nhưng làm thế nào chúng ta có thể lấy lại phiên bản GUID mà chúng ta biết và yêu thích từ sự ghê tởm này?

Lập trình viên, quen thuộc với ASCII, UTF-8, nhị phân, thập lục phân và tất cả những thứ hay ho khác, có thể lao vào với một giải pháp như thế này,

SELECT substr[hex[guid], 1, 8]
|| '-' || substr[hex[guid], 9, 4]
|| '-' || substr[hex[guid], 13, 4]
|| '-' || substr[hex[guid], 17, 4]
|| '-' || substr[hex[guid], 21, 12]
FROM [MyTable]

chuyển đổi giá trị nhị phân của cột

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
5 thành hệ thập lục phân [vì đó là các ký tự 0-9 và A-F của chúng ta], sau đó tách nó thành một chuỗi gồm các ký tự
INSERT INTO mytable ['guid']
VALUES ["not a guid"]
6 [lưu ý rằng cứ hai ký tự tạo thành một byte], rồi sau đó

Nếu có điều gì đó về những kết quả đó khiến bạn thấy kỳ lạ, thì đó là vì thực tế chúng đã sai. Một nhà phát triển thông minh hơn biết rằng khi xử lý các biểu diễn của dữ liệu nhị phân, sẽ không đủ nếu chỉ chuyển đổi từ nhị phân sang thập lục phân và gọi nó là một ngày. Nhà phát triển thông minh hơn nhận ra rằng có thể có một số ý nghĩa đối với thực tế là UUID và GUID luôn được nhìn thấy ở định dạng

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
6 giống nhau, quen thuộc và tự nghĩ: “Có lẽ mình nên kiểm tra Wikipedia về định dạng này. ”

Bạn thấy đấy, GUID không được định nghĩa là “một chuỗi 16 byte, được chia thành 4 byte, 2 byte, 2 byte, 2 byte và 6 byte” mà là

NameLength [byte]Length [base-16]Contentstime_low48integer cho 32 bit thấp của timetime_mid24integer cho 16 bit ở giữa của timetime_hi_and_version244-bit “phiên bản” ở các bit quan trọng nhất, theo sau là 12 bit cao của timeclock_seq_hi_and_res clock_seq_low241-3

Chìa khóa ở đây là việc sử dụng từ số nguyên, có một ý nghĩa rất cụ thể. Không giống như một byte đơn, đọc ngược và xuôi giống nhau, một số nguyên có thêm một gotcha. nó có thể được lưu trữ trong bộ nhớ ở định dạng little-endian hoặc big-endian, với byte ít quan trọng nhất của nó xuất hiện đầu tiên hoặc cuối cùng khi được xem trong bộ nhớ

3 khối đầu tiên của UUID [_______18] phụ thuộc vào thứ tự byte, trong khi hai khối cuối cùng [_______19] thì không. Và để giữ cho mọi thứ phức tạp, nó thậm chí còn kỳ lạ hơn thế. trong khi bạn nghĩ rằng các kiến ​​trúc endian nhỏ như Intel/AMD x86 sẽ sử dụng ít biểu diễn endian cho các số nguyên trong khi các kiến ​​trúc endian lớn như MIPS hoặc PowerPC sẽ sử dụng biểu diễn endian lớn, thì hoàn toàn không phải vậy

Thay vào đó, khi

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
6 UUID/GUID lần đầu tiên được sử dụng, hầu hết các nền tảng [phần mềm] đều sử dụng rõ ràng big endian [hay còn gọi là thứ tự byte mạng] cho UUID, trong khi Microsoft sử dụng biểu diễn được sử dụng bởi kiến ​​trúc mà HĐH đang chạy trên đó [ little endian cho Windows]

Tuy nhiên, có một số phương pháp cho sự điên rồ ở đây. trong khi cách tiếp cận của Microsoft phù hợp với cách hệ điều hành xử lý các số nguyên 4 byte và 2 byte, thì các nền tảng khác lại tập trung vào phần chung của UUID và do đó đã sử dụng một mã hóa cứng [và dễ làm việc hơn với. ] cách tiếp cận big endian bất kể kiến ​​trúc của máy đang được đề cập, nghĩa là các biểu diễn nhị phân của UUID có thể được sao chép sang một kiến ​​trúc/môi trường khác mà vẫn giữ nguyên ý nghĩa

Ngày nay, những khác biệt này là lý do tại sao chúng ta có hai biến thể chính thức của UUID, như được hệ thống hóa trong RFC 4122. Biến thể 1 là lược đồ ban đầu được hầu hết thế giới sử dụng, với các byte cơ bản ở định dạng cuối lớn, trong khi Biến thể 2 là biến thể được Microsoft sử dụng [gặp phải khi xử lý. NET/Win32/COM

SELECT substr[hex[guid], 1, 8]
|| '-' || substr[hex[guid], 9, 4]
|| '-' || substr[hex[guid], 13, 4]
|| '-' || substr[hex[guid], 17, 4]
|| '-' || substr[hex[guid], 21, 12]
FROM [MyTable]
1 phiên bản]

Và đó là lý do tại sao chỉ cần chuyển đổi một cột hướng dẫn

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
7 thành hệ thập lục phân bằng hàm
SELECT substr[hex[guid], 1, 8]
|| '-' || substr[hex[guid], 9, 4]
|| '-' || substr[hex[guid], 13, 4]
|| '-' || substr[hex[guid], 17, 4]
|| '-' || substr[hex[guid], 21, 12]
FROM [MyTable]
3 của SQL và sau đó tách chuỗi sau một số ký tự nhất định sẽ không hiệu quả. Thay vào đó, chúng ta phải sử dụng một sự gớm ghiếc như thế này

INSERT INTO mytable ['guid']
VALUES ["not a guid"]
3

Điều cuối cùng mang lại cho chúng tôi kết quả chính xác mà chúng tôi đang tìm kiếm

Nếu bạn quan tâm đến việc tối ưu hóa hơn nữa hiệu suất của các bảng chứa UUID, thì bài viết này từ Percona là một bài viết hay. Tuy nhiên, xin lưu ý rằng chỉ cần sử dụng UUIDv4 sẽ loại bỏ hoàn toàn sự cố mà chúng giải quyết, vì kết quả hoàn toàn ngẫu nhiên

  1. Đối với những người theo dõi ở nhà, bạn có thể dễ dàng tự kiểm tra điều này mà không cần tìm bảng ASCII bằng cách chỉ cần nhấn F12 và nhập

    SELECT substr[hex[guid], 1, 8]
    || '-' || substr[hex[guid], 9, 4]
    || '-' || substr[hex[guid], 13, 4]
    || '-' || substr[hex[guid], 17, 4]
    || '-' || substr[hex[guid], 21, 12]
    FROM [MyTable]
    
    4 vào phần thay thế.  

  2. Lần cuối cùng bạn nhìn thấy rất nhiều GUID bắt đầu bằng một chuỗi các số 0 là khi nào?

  3. Có, chúng tôi đang cố tình giả vờ Windows Server 2000 dành cho Alpha, với hỗ trợ hai đầu có thể định cấu hình của DEC Alpha chưa bao giờ xảy ra. Bây giờ đi đi, bạn thông minh aleck.  

    Làm cách nào để chuyển đổi BLOB thành văn bản trong SQL?

    Truy vấn. CHỌN chuyển đổi [Tệp sử dụng utf8] từ demo_table ; .

    Làm cách nào để chuyển đổi BLOB thành chuỗi trực tuyến?

    Để sử dụng bộ chuyển đổi Hex sang String, bạn chỉ cần nhập giá trị thập lục phân mà bạn muốn chuyển đổi vào bộ chuyển đổi và nhấn nút Hex to String. The converter will then generate the corresponding string value. You can then copy and paste this value into the desired location.

    Làm cách nào để chuyển đổi SQL BLOB thành chuỗi trong Java?

    Blob blob = rs. getBlob[cloumnName[i]]; . getBytes[1, [int] blob. chiều dài[]];

    Làm cách nào để đọc kiểu dữ liệu BLOB trong SQL?

    Kiểu dữ liệu BLOB .
    cú pháp. { BÃI. ĐỐI TƯỢNG LỚN NHỊ PHÂN } [ [ độ dài [{K. m. G }] ] ]
    Mặc định. BLOB không có độ dài chỉ định được mặc định là hai gigabyte [2.147.483.647]
    Loại Java thời gian biên dịch tương ứng. java. sql. Bãi
    Loại siêu dữ liệu JDBC [java. sql. .
    Thông tin liên quan
    Ví dụ

Chủ Đề