我试图调试别人的SQL报表,并已将底层报表查询放入SQL 2012的查询窗口。
报告要求的参数之一是一个整数列表。这是通过一个多选下拉框在报表上实现的。报告的底层查询在where子句中使用这个整数列表。
select *
from TabA
where TabA.ID in (@listOfIDs)
我不想修改我正在调试的查询,但我不知道如何在SQL Server上创建一个变量,可以保存这种类型的数据来测试它。
如。
declare @listOfIDs int
set listOfIDs = 1,2,3,4
没有可以保存整数列表的数据类型,因此如何在SQL Server上使用与报表相同的值运行报表查询?
如果你使用的是字符串列表,SQL中有一个新函数叫做string_split。
Ref Link STRING_SPLIT (Transact-SQL)
DECLARE @tags NVARCHAR(400) = 'clothing,road,,touring,bike'
SELECT value
FROM STRING_SPLIT(@tags, ',')
WHERE RTRIM(value) <> '';
你可以这样传递这个查询:
SELECT *
FROM [dbo].[yourTable]
WHERE (strval IN (SELECT value FROM STRING_SPLIT(@tags, ',') WHERE RTRIM(value) <> ''))
对于SQL Server 2016+和Azure SQL数据库,添加了STRING_SPLIT函数,这将是这个问题的完美解决方案。以下是文档:
https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
这里有一个例子:
/*List of ids in a comma delimited string
Note: the ') WAITFOR DELAY ''00:00:02''' is a way to verify that your script
doesn't allow for SQL injection*/
DECLARE @listOfIds VARCHAR(MAX) = '1,3,a,10.1,) WAITFOR DELAY ''00:00:02''';
--Make sure the temp table was dropped before trying to create it
IF OBJECT_ID('tempdb..#MyTable') IS NOT NULL DROP TABLE #MyTable;
--Create example reference table
CREATE TABLE #MyTable
([Id] INT NOT NULL);
--Populate the reference table
DECLARE @i INT = 1;
WHILE(@i <= 10)
BEGIN
INSERT INTO #MyTable
SELECT @i;
SET @i = @i + 1;
END
/*Find all the values
Note: I silently ignore the values that are not integers*/
SELECT t.[Id]
FROM #MyTable as t
INNER JOIN
(SELECT value as [Id]
FROM STRING_SPLIT(@listOfIds, ',')
WHERE ISNUMERIC(value) = 1 /*Make sure it is numeric*/
AND ROUND(value,0) = value /*Make sure it is an integer*/) as ids
ON t.[Id] = ids.[Id];
--Clean-up
DROP TABLE #MyTable;
查询结果为1,3
假设变量类似于:
CREATE TYPE [dbo].[IntList] AS TABLE(
[Value] [int] NOT NULL
)
存储过程以这种形式使用它:
ALTER Procedure [dbo].[GetFooByIds]
@Ids [IntList] ReadOnly
As
你可以创建IntList并像这样调用这个过程:
Declare @IDs IntList;
Insert Into @IDs Select Id From dbo.{TableThatHasIds}
Where Id In (111, 222, 333, 444)
Exec [dbo].[GetFooByIds] @IDs
或者如果你自己提供了IntList
DECLARE @listOfIDs dbo.IntList
INSERT INTO @listofIDs VALUES (1),(35),(118);