Как преобразовать строку символов в uniqueidentifier и использовать функцию Stuff?

#sql #sql-server #database #tsql

Вопрос:

Я использую функцию для генерации результата. Сейчас я сталкиваюсь с тем, что я передаю идентификатор элемента в качестве параметра, и в настоящее время я использую МАТЕРИАЛ для поиска кода элемента и объединения результатов. Однако я, получив сообщение об ошибке, сказал, что Conversion failed when converting from a character string to uniqueidentifier.

Мой текущий результат перед использованием МАТЕРИАЛА: From Date : 01-01-2021 to 31-03-2021 Item No: IN ('a70014a3-2e00-41f0-9c3e-6fb8c4f2ab60','26dd67c1-fe37-41fa-b8c5-ff033928a291')

Мой ожидаемый результат: From Date : 01-01-2021 to 31-03-2021 Item No: IN ('ITM001','ITM021')

Пожалуйста, посмотрите на мою скрипку. Скрипка SQL

Используемый параметр: SELECT[dbo].[func_ReportCriteria2]('2021-01-01','2021-03-31','''a70014a3-2e00-41f0-9c3e-6fb8c4f2ab60'',''26dd67c1-fe37-41fa-b8c5-ff033928a291''') AS 'RESULT 2'

 --using STUFF
CREATE FUNCTION [dbo].[func_ReportCriteria2] 
(@FromDate DateTime
,@ToDate DateTime
,@Item_List NVARCHAR(MAX)
)
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @CRITERIA NVARCHAR(MAX) 
    DECLARE @sqlCommand NVARCHAR(MAX)
    DECLARE @ItemResult NVARCHAR(MAX)
    SET @sqlCommand = ''

    IF(ISNULL(@Item_List,'') != '')
    BEGIN
    --find ItemCode and concatenate based on ItemGuid 
    --error occur here
    SET @ItemResult = STUFF( (SELECT ','   ItemCode 
                  FROM Item
                  WHERE ItemGuid IN (@Item_List)
                  FOR XML PATH('')), 1, 1, '')
    
    SET @sqlCommand = 'Item No: IN ('  @ItemResult  ') '
    END

    SET @CRITERIA = 'From Date : '   CONVERT(NVARCHAR(19),@FromDate,105)   ' to '   CONVERT(NVARCHAR(19),@ToDate,105)
      CHAR(13) CHAR(10)   @sqlCommand

RETURN @CRITERIA
END
 

Комментарии:

1. С ItemGuid IN (@Item_List) @ItemList параметром не преобразуется во встроенный код. Вам нужно будет выполнить это с помощью функции string_split() или аналогичной функции, чтобы сгенерировать набор значений.

2. Ваш вопрос мне не совсем ясен, но это может вам помочь: (1) если вы хотите передать список значений, вам следует использовать параметры с табличными значениями вместо строки текста с разделителями. (2) поскольку вы используете строку, включающую строку, которая НЕ имеет формата «xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx», вы получаете эту ошибку. (3) Если вы хотите разделить строку, вы можете использовать STRING_SPLIT для простого случая, в котором есть определенный разделительный текст, или JSON/XML для более сложных случаев, которые вам нужно сначала проанализировать.

Ответ №1:

Пожалуйста, проверьте, соответствует ли это вашим потребностям:

 declare @FromDate CHAR(10) ,@ToDate CHAR(10), @Item_List nvarchar(MAX)
select 
    @FromDate  = '2021-01-01',-- make sure to convert the DATE from the table to NVARCHAR using style 120
    @ToDate    = '2021-03-31',-- make sure to convert the DATE from the table to NVARCHAR using style 120
    @Item_List = '''a70014a3-2e00-41f0-9c3e-6fb8c4f2ab60'',''26dd67c1-fe37-41fa-b8c5-ff033928a291'''

------------------ Solution --------------------
-- Important! No reason for scalar function! Use it inline your query directly
SELECT 
    N'From Date : '   @FromDate   ' to '   @ToDate   N' Item No: IN ('   STRING_AGG('''' ItemName '''',',')   N')' 
FROM Item
WHERE ItemGuid in (
    -- Your string includes quotes which we must clear befor CONVERT to GUIDE
    SELECT REPLACE([value],'''','') FROM STRING_SPLIT(@Item_List, ',')
)
 

Обратите внимание! объединение входного текста в строку может быть небезопасным и НЕ рекомендуется. У него есть потенциал для SQL-инъекции!

Примечание: Вы, вероятно, планируете динамический запрос, который будет ВЫБИРАТЬ данные из таблицы, используя приведенную выше строку, которую вы просили построить. В данном случае это похоже на «проблему XY», так как вам, вероятно, вообще не нужно создавать эту строку. Вы можете использовать тот же подход для разделения ввода строк и выполнения прямого запроса SELECT из вашей таблицы. Если бы мы знали, каков ваш конечный запрошенный результат, то мы могли бы помочь и в этом, но подход тот же, что и в приведенном выше коде

Ответ №2:

Попробуйте применить преобразование itemguid

 Change WHERE ItemGuid IN (@ItemList)

To WHERE cast(ItemGuid as NVARCHAR(MAX)) IN (@ItemList)