【问题标题】:Dynamic SQL output of a query to a variable查询到变量的动态 SQL 输出
【发布时间】:2017-12-12 04:28:01
【问题描述】:

我想将动态 SQL 的结果输出到一个名为 @Count 的变量中,但不确定要使用什么语法甚至代码来完成此操作。

代码如下:

declare @tab nvarchar(255) = 'Person.person'

declare @Count int
declare @SQL nvarchar(max) = 'select  count(*) from '+ @tab


exec(@SQl)


select @Count

谢谢

【问题讨论】:

  • 为什么要为此使用动态sql...
  • 除非您绝对无法避免,否则我会避免使用动态 SQL。你最终没有自动完成,而且总的来说它更容易出错。
  • 另外,还有 SQL 注入问题。这是一个不容忽视的大问题。
  • 可能,是的。取决于您通过什么以及它的来源,但在这方面很难保证来源是干净的。
  • @user2366842 我的回答确实保证源是干净的。

标签: sql sql-server tsql


【解决方案1】:

这是另一种安全解决 SQL 注入问题的方法:

/* Counts the number of rows from any non-system Table, *SAFELY* */

-- The table name passed
DECLARE @PassedTableName as NVarchar(255) = 'Person.Person';

-- Make sure this isn't a SQL Injection attempt
DECLARE @ActualTableName AS NVarchar(255)

SELECT  @ActualTableName = TABLE_SCHEMA + '.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME   = PARSENAME(@PassedTableName,1)
  AND TABLE_SCHEMA = PARSENAME(@PassedTableName,2)

-- make a temp table to hold the results
CREATE TABLE #tmp( cnt INT );

-- create the dynamic SQL
DECLARE @sql AS NVARCHAR(MAX)
SELECT @sql = 'SELECT COUNT(*) FROM ' + @ActualTableName + ';'

-- execute it and store the output into the temp table
INSERT INTO #tmp( cnt )
EXEC(@SQL);

-- Now, finally, we can get it into a local variable
DECLARE @result AS INT;
SELECT @result = cnt FROM #tmp;

【讨论】:

  • 我无法对此进行测试,但是您确定可以将 exec 的结果插入到另一个表中吗?我在 Sybase 上对其进行了测试(目前我最接近 SQLServer),我无法将动态 sql 结果插入到表中。
  • @RobbieToyota 是的,我确定。我一直这样做,而且我在发布之前测试了代码。
  • @RobbieToyota 这是带有示例的文档的链接。 docs.microsoft.com/en-us/sql/t-sql/statements/…
【解决方案2】:

您可以利用sp_executesql 执行您的count() 查询,并将其输出@Count。

试试这个:

-- Set the table to count from
declare @tab nvarchar(255) = 'Person.person'

-- Assign the SQL query
declare @SQL nvarchar(255) = N'SELECT count(*) FROM ' + @tab

-- Pepare for sp_executesql
declare @Count int
declare @Params nvarchar(100) = N'@Count int output'

-- Set the count to @Count
exec sp_executesql @SQL, @Params, @Count=@Count output

-- Output @Count
select @Count

最后一件事:Person.person 看起来您可能正在尝试从 Person 表中引用 person 列。但是上面的查询是您在问题中尝试实现的内容的文字表示。

【讨论】:

  • 嗯。你真的试过这个吗?
  • 动态 SQL 上下文无法查看或修改外部上下文中的变量。
  • 好点;我没有想到关于变量范围的想法。 @Jesse 刚刚发布了我将在这里提到的答案。我会尽快修改它以使用 sp_executeSql。
  • 您好,我已经尝试过了,但我收到此错误消息,消息 156,级别 15,状态 1,行 1 关键字“SELECT”附近的语法不正确。 (1 行受影响)
  • 再次感谢 Rob,这对像我这样的新手很有帮助,所以我接受了你的回答,因为它是在我的问题的上下文中
【解决方案3】:

以下问题与您在此处提出的问题几乎相同。

sp_executeSql with output parameter

DECLARE @retval int   
DECLARE @sSQL nvarchar(500);
DECLARE @ParmDefinition nvarchar(500);

DECLARE @tablename nvarchar(50)  
SELECT @tablename = N'products'  

SELECT @sSQL = N'SELECT @retvalOUT = MAX(ID) FROM ' + @tablename;  
SET @ParmDefinition = N'@retvalOUT int OUTPUT';

EXEC sp_executesql @sSQL, @ParmDefinition, @retvalOUT=@retval OUTPUT;

SELECT @retval;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2011-08-01
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    相关资源
    最近更新 更多