繁体   English   中英

将多个值发送到存储过程并在 IN 运算符中使用

[英]Sending multiple values to stored procedure and use it in IN operator

我正在尝试创建一个表单,用户可以在其中更改数据库中的一些数据并且他需要提供的东西很少,这就是程序的外观

ALTER procedure [dbo].[ChangePrice] 
( 
    @type int, 
    @quality nvarchar(1000), 
    @dim1_from decimal(10, 2), 
    @dim1_to decimal(10, 2), 
    @dim2_from decimal(10, 2), 
    @dim2_to decimal(10, 2),
    @od_from decimal(10, 2), 
    @od_to decimal(10, 2),
    @price decimal(10, 2), 
    @price_m decimal(10, 2)
) 
AS 
BEGIN
UPDATE list
SET 
price=ISNULL(@price, price),
price_m=ISNULL(@price_m, price_m)
WHERE
    type=@type
    AND dim1 BETWEEN @dim1_from AND @dim1_to
    AND (dim2 BETWEEN @dim2_from AND @dim2_to OR @dim2_from IS NULL)
    AND od BETWEEN @od_from AND @od_to  
    AND quality IN (@quality)
END

这工作正常,这些数据大部分都是数字,我每个变量只发送一个数字,但问题在于变量@quality 在一个字符串数据库中,当我只发送一个字符串时它工作正常,但我想发送多个质量数,所以我尝试像“quality1,quality2,quality3”一样发送它,但它没有用,我认为我明白为什么。

在这个线程上,我发现了一些看起来可以帮助我但我无法让它工作的东西使用变量来表示多个值

这是我做的

ALTER procedure [dbo].[ChangePrice] 
( 
@type int, 
@quality nvarchar(1000), 
@dim1_from decimal(10, 2), 
@dim1_to decimal(10, 2), 
@dim2_from decimal(10, 2), 
@dim2_to decimal(10, 2),
@od_from decimal(10, 2), 
@od_to decimal(10, 2),
@price decimal(10, 2), 
@price_m decimal(10, 2)
) 
AS 
BEGIN


DECLARE @sql NVARCHAR(MAX) = N'
UPDATE lista_cevi
SET 
price=ISNULL('+@price+', price),
price_m=ISNULL('+@price_m+', price_m)
WHERE
    type='+@type+'
    AND dim1 BETWEEN '+@dim1_from+' AND '+@dim1_to+'
    AND (dim2 BETWEEN '+@dim2_from+' AND '+@dim2_to+' OR '+@dim2_from+' IS NULL)
    AND od BETWEEN '+@od_from+' AND '+@od_to+'
    AND quality IN (''' +REPLACE(@quality, ',',''',''')+''')';
exec sp_executesql @sql
END

我正在使用 Postman 对其进行测试,并且大多数时候我都会收到此错误

将 varchar 转换为数字数据类型的算术溢出错误。

我想这与数字变量有关,但我不知道如何解决。 当我删除大部分内容并仅保留WHERE quality IN (@quality)时,它看起来可以正常工作,所以现在的问题在于其他变量。 我尝试使用CAST()使它们成为nvarchar ,但这也给了我一些其他类型的错误。

有谁知道如何解决它,或者有其他方法可以发送多个数据吗? 我正在使用 React 和 NodeJs,数据库是 SQL 服务器。

我能想到的最后一个解决方案是 map 通过所有选择的质量并分别调用每种质量的程序,不确定这是否是最好的主意?

这是另一种方法。 无动态 SQL。

它使用 XQuery 对参数进行标记,并将其转换为关系数据集。

它将从 SQL Server 2012 开始工作。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, quality NVARCHAR(10), City VARCHAR(50));
INSERT INTO @tbl (quality , City) VALUES
('10', 'Miami'),
('45', 'Orlando'),
('50', 'Dallas'),
('70', 'Houston');
-- DDL and sample data population, end

DECLARE @quality NVARCHAR(1000) = '22,45,50,105,'   -- here is your parameter
   , @separator CHAR(1) = ',';

DECLARE @parameter XML = TRY_CAST('<root><r><![CDATA[' + 
      REPLACE(@quality, @separator, ']]></r><r><![CDATA[') + 
      ']]></r></root>' AS XML);

;WITH rs AS
(
   SELECT c.value('.', 'NVARCHAR(10)') AS quality
   FROM @parameter.nodes('/root/r/text()') AS t(c)
)
SELECT t.* 
FROM @tbl AS t INNER JOIN 
   rs ON t.quality = rs.quality;

Output

+----+---------+---------+
| ID | quality |  City   |
+----+---------+---------+
|  2 |      45 | Orlando |
|  3 |      50 | Dallas  |
+----+---------+---------+

如果@quality是 CSV 字符串,那么您可以简单地使用string_split
(如果您的 Sql 服务器版本支持它)

... 
AND quality IN (select value from STRING_SPLIT(@quality,','))
... 

考虑到您的前端,使用 json 数组将这些值传递给程序,然后使用OPENJSON运算符解析 sql 中的 @quality 参数会更自然和可靠。

例如,@quality 参数的值可能如下所示:

'["quality1","quality2","quality3"]'

然后该过程可以采用以下形式:

ALTER procedure [dbo].[ChangePrice] 
( 
    @type int, 
    @quality nvarchar(max), 
    @dim1_from decimal(10, 2), 
    @dim1_to decimal(10, 2), 
    @dim2_from decimal(10, 2), 
    @dim2_to decimal(10, 2),
    @od_from decimal(10, 2), 
    @od_to decimal(10, 2),
    @price decimal(10, 2), 
    @price_m decimal(10, 2)
) 
AS 
BEGIN
UPDATE list
SET 
price=ISNULL(@price, price),
price_m=ISNULL(@price_m, price_m)
FROM list INNER JOIN OPENJSON(@quality) AS qualities ON list.quality = qualities.value
WHERE
    type=@type
    AND dim1 BETWEEN @dim1_from AND @dim1_to
    AND (dim2 BETWEEN @dim2_from AND @dim2_to OR @dim2_from IS NULL)
    AND od BETWEEN @od_from AND @od_to
END

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM