8

我正在编写一个存储过程,我需要在该过程中动态构造一个 SQL 语句来引用传入的表名。

我需要让这个 SQL 语句返回一个结果,然后我可以在整个过程的其余部分使用该结果。

我试过使用临时表和所有东西,但我不断收到一条消息,我需要声明变量等。

例如:

DECLARE @FiscalYear INT    
DECLARE @DataSource NVARCHAR(25)
DECLARE @SQL NVARCHAR(250)
SELECT @DataSource = 'CustomerCosts20120328'
DECLARE @tempFiscalYear TABLE ( FiscalYear INT ) 
SELECT @SQL = 'INSERT INTO @tempFiscalYear SELECT DISTINCT FiscalYear FROM ' + @DataSource
EXEC(@SQL)
SELECT @FiscalYear = FiscalYear FROM @tempFiscalYear

或者...

DECLARE @FiscalYear INT  
DECLARE @DataSource NVARCHAR(25)
DECLARE @SQL NVARCHAR(250)
SELECT @DataSource = 'CustomerCosts20120328'
SELECT @SQL = 'SELECT DISTINCT @FiscalYear = FiscalYear FROM ' + @DataSource
EXEC(@SQL)

无论如何都可以在不使用实际表格的情况下做到这一点?

谢谢。

4

2 回答 2

8

您是否尝试过类似的方法:

DECLARE @FiscalYear INT, @DataSource NVARCHAR(25), @SQL NVARCHAR(250);
SET @DataSource = N'CustomerCosts20120328';
SET @SQL = N'SELECT DISTINCT @FiscalYear = FiscalYear FROM ' + @DataSource;
EXEC sp_executesql @SQL, N'@FiscalYear INT OUTPUT', @FiscalYear OUTPUT;

PRINT @FiscalYear;

您需要确保在 nvarchar 字符串前面加上 N,例如SELECT @SQL = N'SELECT ....

此外,您知道如果查询返回多行,分配给的值@FiscalYear是完全任意的,对吧?虽然您可能希望从该表中获得一个值,但使用MAX()TOP 1 ... ORDER BY确保只分配一个单一的、可预测的值并没有什么坏处。

于 2012-04-24T13:21:46.483 回答
6

首先,您需要知道,使用动态 SQL,您将面临 SQL 注入攻击的风险,您应该在使用之前先查看此链接。完成此操作后,您可以将第一个查询更改为:

DECLARE @FiscalYear INT    
DECLARE @DataSource NVARCHAR(25)
DECLARE @SQL NVARCHAR(250)
SELECT @DataSource = 'CustomerCosts20120328'
DECLARE @tempFiscalYear TABLE ( FiscalYear INT ) 
SELECT @SQL = 'SELECT DISTINCT FiscalYear FROM ' + @DataSource

INSERT INTO @tempFiscalYear
EXEC(@SQL)

SELECT @FiscalYear = FiscalYear FROM @tempFiscalYear

您还应该考虑@AaronBertrand 对@FiscalYear参数分配的评论。

于 2012-04-24T13:25:25.613 回答