Как SQL вставить необработанное / двоичное значение поля из массива байтов / целых чисел, используя VBScript (или VB6)? - PullRequest
3 голосов
/ 28 мая 2009

Кто-нибудь знает, как передать несколько байтов в поле Binary (или varbinary), используя SQL и в идеале в ADO (classic) и VBScript (или Visual Basic 6)?

Я хочу закодировать 10-20 (может быть, больше) байтов данных и сохранить эти данные в поле базы данных SQL. (Это не MS-SQLSVR, но я надеюсь, что стандартный формат, поддерживаемый SQL, будет работать!)

Байты доступны либо в виде строки байтов, полученных с помощью AscB / ChrB, OR, либо в виде массива байтов (на самом деле варианты байтов типа, полученных через 'cbyte') и сохраняемых в массиве.

Первый вариант: использование формата строки У меня был некоторый (ограниченный) успех при создании вставки SQL как:

x = ".>?hD-&91k[="    '<psuedo string of chars, some unprintable
Insert Into rawtest (byt) Values (CAST('" & x & "' as SQL_BINARY(12)))

Но я обеспокоен тем, что строковые нули будут обрезать данные в поле, а другие непечатные управляющие символы будут мешать обработке данных. Есть ли способ избежать этого?

Второй вариант: массив байтов Я могу достаточно легко поместить данные в массив, но не вижу, как перейти к оператору SQL Insert. Если я попытаюсь передать 12 байтов, вставка завершится неудачно из-за попытки CAST сохранить данные в целое число (4 байта). Если я передаю один байт, он работает, например:

x = a(0)

И продолжает работать в течение 4 байтов, но завершается ошибкой, когда целое число переполняется. Кроме того, это переупорядочивает данные

Я пытался использовать различные обходные пути:

Insert Into rawtest (byt) Values (CAST('12,34,45' as SQL_BINARY(12)))
Insert Into rawtest (byt) Values (CAST(&h12&h34 as SQL_BINARY(12)))
Insert Into rawtest (byt) Values (CAST(0x123456789012 as SQL_BINARY(12)))

Я также пробовал подобные комбинации с:

Insert Into rawtest (byt) Values (CONVERT('" & x & "', SQL_BINARY)

Но все это терпит неудачу!

В идеале мне нужен метод, любой метод, который принимает небольшой двоичный массив размером до 20 байтов (в идеале полный диапазон байтов 0-255, но может занимать меньше) и передает их через простой, сырой двоичный SQL поле.

В идеале мне нужно сделать это в VBScript / ADO, но я могу использовать решение на основе VB6, если оно доступно. Я хочу, чтобы это был «сырой» двоичный файл, я не хочу использовать ascii-кодировку, такую ​​как Base64.

Я гуглил до тех пор, пока не потерял сознание и почти не нашел ничего общего с бинарными полями в SQL.

Вы можете помочь? Любые ответы приветствуются. Многие спасибо.

Ответы [ 3 ]

5 голосов
/ 29 мая 2009

Классический ADO может манипулировать очень большими (> 8000) полями varbinary и image (blob) напрямую без чанкинга. Ниже приведен пример для MS SQL Server, который вставляет двоичные данные в таблицу с полем INT ID и полем varbinary (100). В этом примере параметризованный SQL-запрос вставляет двоичные данные из Variant. Вариант просто должен быть заполнен двоичными данными.

Dim vntBlobData As Variant
vntBlobData = "ReplaceThisWithBinaryData - A byte array will work"

Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = "Provider = sqloledb; Data Source = DBServerName; Initial Catalog = DBName; User ID = UserID; Password = Password; Persist Security Info = False"
cn.Open

Dim strQry As String
strQry = "INSERT INTO TestBinaryTable (ID, BlobData) VALUES (?, ?)"

Dim cm As ADODB.Command
Set cm = New ADODB.Command
cm.ActiveConnection = cn
cm.CommandText = strQry
cm.Parameters.Append cm.CreateParameter("@ID", adInteger, adParamInput, , 1)
cm.Parameters.Append cm.CreateParameter("@BlobData", adVarBinary, adParamInput, 100, vntBlobData)
cm.CommandType = adCmdText
cm.Execute
1 голос
/ 01 июня 2009

Мэтт дал мне подсказку к решению: хотя цель не является полем большого двоичного объекта, и большая часть кода указывает, как передать строку в БД через ADO, мне понадобился бит для создания байтов чтобы передать в переменную 'vntBlobData', создав VBS 'строку байтов' из исходных байтов, используя charb / ascb, я получил свое решение. Теперь у меня есть решение VBS (и использующий правильный байтовый массив, тоже решение VB6!) Большое спасибо Мэтт.

'VBS $ 2Bin:

Function a2b(x)
    For i = 1 To Len(x)+1 Step 2
        d = Mid(x, i, 2)
        a2b = a2b & chrb(CByte(d))
    Next
End Function

'VBS Bin2 $

Function eb2s(c)
    If IsNull(c) Then
        eb2s = ""
    else
        For i = 1 To lenb(c)
        eb2s = eb2s & ascb(Midb(c, i, 1))
        Next
    End if
End Function
1 голос
/ 28 мая 2009

VB6 может обращаться к двоичным столбцам с помощью методов GetChunk и AppendChunk класса поля ADO. См. Эту статью KB .

Это сообщение в блоге имеет функцию для преобразования шестнадцатеричной строки в varbinary:

CREATE FUNCTION dbo.HexStrToVarBinary(@hexstr varchar(8000))
RETURNS varbinary(8000)
AS
BEGIN 
    DECLARE @hex char(1), @i int, @place bigint, @a bigint
    SET @i = LEN(@hexstr) 

    set @place = convert(bigint,1)
    SET @a = convert(bigint, 0)

    WHILE (@i > 0 AND (substring(@hexstr, @i, 1) like '[0-9A-Fa-f]')) 
     BEGIN 
        SET @hex = SUBSTRING(@hexstr, @i, 1) 
        SET @a = @a + 
    convert(bigint, CASE WHEN @hex LIKE '[0-9]' 
         THEN CAST(@hex as int) 
         ELSE CAST(ASCII(UPPER(@hex))-55 as int) end * @place)
    set @place = @place * convert(bigint,16)
        SET @i = @i - 1

     END 

    RETURN convert(varbinary(8000),@a)
END
...