XQuery [value()]: ожидался строковый литерал

Я хочу выполнить этот код:

if exists(select * from FileUploadFileTable..sysobjects where  xtype='u' and name='##Tmp830963'  )
        drop table  ##Tmp830963
        CREATE table  ##Tmp830963 (RowId int,Files varchar(MAX) ,Files_Name NVARCHAR(MAX), Files_Size bigint,Job_Id  bigint, Files_Type VARCHAR(MAX) , User_id bigint  ,User_Name  NVARCHAR(MAX)) Insert into ##Tmp830963(RowId,Files,Files_Name,Files_Size  , Files_Type)  select A.row_num,A.Items,O.Items,B.Items,C.Items
         from(
        SELECT Items,row_number() over (order by (select 0)) as row_num
        FROM  dbo.Func_Split('/9j/AqAAAAB4CgAwAEAAABAAAAAAA', '^') ) A
        join
        (SELECT Items,row_number() over (order by (select 0)) as row_num
        FROM  dbo.Func_Split('tt^', '^') ) O  on  O.row_num=A.row_num 
         join
        (SELECT Items,row_number() over (order by (select 0)) as row_num
        FROM  dbo.Func_Split('12^', '^'))B       on  A.row_num=B.row_num 
         join
         (SELECT Items,row_number() over (order by (select 0)) as row_num
         FROM  dbo.Func_Split('png^', '^'))C
         on   C.row_num=A.row_num 
        update  ##Tmp830963 set User_Name=100update  ##Tmp830963 set Job_Id='20' update  ##Tmp830963 set User_id='1' select * from  ##Tmp830963  DECLARE @OutputTbl TABLE (ID uniqueidentifier)    INSERT INTO [Uploads]  ([file_stream],[name])  OUTPUT INSERTED.stream_id INTO @OutputTbl(ID)  select cast(N'' as xml).value('xs:base64Binary(sql:variable(Files))', 'varbinary(max)') ,Files_Name   from ##Tmp830963 while (select count(*)  from @OutputTbl) > 0 begin INSERT INTO [dbo].[FileDescriptions]  ([User_ID] ,[FileName],Stream_id,[Size],Job_Id)   select   [User_id] ,cast((select MAX(ID) from @OutputTbl   )  as nvarchar(max) ),(select MAX(ID) from @OutputTbl) , Files_Size  ,  Job_Id   from ##Tmp830963  where RowId=(select top 1(RowId) from ##Tmp830963)  delete @OutputTbl  where ID =(select MAX(ID) from @OutputTbl )  end 

Но я получаю эту ошибку:

XQuery [value()]: A string literal was expected

В этой строке:

cast(N'''' as xml).value(''xs:base64Binary(sql:variable(Files))''

Каков тип данных @TempTable? Чтобы использовать переменную для имени таблицы в динамическом SQL, она должна иметь тип SYSNAME.

Thermos 18.04.2019 16:15

У вас сейчас гораздо большие проблемы; что SQL - это кошмар для инъекций. Вам нужно заключать имена объектов в кавычки (QUOTENAME очень полезно) и параметризовать оператор, а не вводить их (sp_executesql поддерживает параметризованные запросы). После этого используйте PRINT @SQL; или SELECT @SQL;, чтобы проверить значение вашего динамического SQL, отладить его, а затем отладить ваш SQL, который генерирует оператор. я боюсь, что мы не можем помочь вам больше, чем это; мы не можем запустить этот SQL или проверить значение @Sql.

Larnu 18.04.2019 16:15

Что вы пытаетесь получить из пустого xml?

Luis Cazares 18.04.2019 16:25

@LuisCazares, пустой XML - это уловка, позволяющая использовать собственные методы типа XML без реального наличия XML. Этот прием используется для перевода base64 в varbinary. Некоторые примеры: 1) вычисление формулы: SELECT CAST('' AS XML).value('((3.0+4.2)*.5) div 3.5','real') или 2) TRY_CAST в версиях до v2012: DECLARE @s VARCHAR(10)='blah'; /*use a number instead*/ SELECT CAST('' AS XML).value('sql:variable("@s") cast as xs:int?','int').

Shnugo 18.04.2019 17:10
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
1 048
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

На первый взгляд это выглядит немного странно. Я почти уверен, что это можно решить по-другому.

Вы пытаетесь перевести base64 в varbinary, верно?
Ну, XML-подход является рекомендуемым способом достижения этого. Однако ваша проблема, похоже, находится здесь:

cast(N'''' as xml).value(''xs:base64Binary(sql:variable(Files))''

Это ваша попытка динамически создать необходимый оператор, отсюда и двойные одинарные кавычки. Это переведет на

cast(N'' as xml).value('xs:base64Binary(sql:variable(Files))'

Проблема здесь в том, что sql:variable() ожидает имя объявленной переменной как строковый литерал. Кроме того, value() ожидает два аргумента: Xpath и тип данных. Вам нужно что-то вроде этого

cast(N'' as xml).value('sql:variable("@Files")','varbinary(max)')

Возможно, вам понадобится sql:column("SomeColumn"), который позволяет использовать значение столбца.

Один пример, чтобы продемонстрировать это

--We use FOR XML to get the binary 0x1234 as base64
SELECT 0x1234 FOR XML PATH(''); --returns "EjQ = "

--Now I place the corresponding base64 string in a string variable 
DECLARE @base64 VARCHAR(100)='EjQ=';

--And this is, how XML is returning the binary 0x1234 from the base64-string
SELECT CAST('' AS XML).value('sql:variable("@base64")','varbinary(max)');

И это вернет то же самое и выглядит немного проще:

SELECT CAST(@base64 AS XML).value('.','varbinary(max)');

Проверьте это для табличного подхода

Таблица @base64 является объявленной табличной переменной, просто используйте вместо нее исходную таблицу:

--Declare a table variable with one string column and insert the base64 of 0x1234
DECLARE @base64 TABLE(Files VARCHAR(100));
INSERT INTO @base64 VALUES('EjQ=');

--use the same trick as above to get the varbinary back
SELECT CAST(Files AS XML).value('.','varbinary(max)')
FROM @base64;

спасибо, я хочу использовать файлы .. Файлы - это база данных столбцов. Файлы не объявляются как поле базы данных.

SAEED SAEEDI 18.04.2019 17:17

спасибо cast(N'''' as xml).value(''xs:base64Binary(sql:column("Files")) но см. ошибку Запись файла не может иметь значение NULL для потока данных, связанного со строкой. Вставить данные файла или используйте 0x для вставки файла нулевой длины

SAEED SAEEDI 18.04.2019 17:42

Другие вопросы по теме