SQL:基于变量的列名

时间:2017-07-05 10:50:48

标签: sql sql-server tsql

我有一个临时表aaa,我将其用作数组。

    USE tempdb
    GO

    IF OBJECT_ID('tempdb..aaa') IS NOT NULL DROP TABLE aaa
    CREATE TABLE aaa (
        #1 char(40),
        #2 char(40),
        #3 char(40)
    );
    insert into aaa values ('aaaa','qqqq','eeee');
    declare @sql varchar(40);
    declare @var varchar(40)='#3';
    set @sql= '(select '+@var +' from aaa)';
       print @sql;

我想要实现的是将'(select '+@var +' from aaa)'的执行值存储到变量@sql中,即:eeee而不仅仅是字符串(select #3 from aaa)

我知道''这不是SQL应该如何工作''但是在SO上阅读了320个问题后(我的历史标签可以证明)我没有想法:)

4 个答案:

答案 0 :(得分:3)

[1] tempdb..aaa不是临时表。相反,它只不过是在tempdb数据库中创建的标准表,这意味着当SQL Server数据库引擎服务重新启动时删除({{1每次启动服务/ 重新启动时,都会创建重新数据库。

[2]如果你想使用临时表,那么你可以使用以下语法:

tempdb

CREATE TABLE #Array (RowNum INT NOT NULL, Val AS VARCHAR(10)) -- See # prefix that means a local temp table 

示例:

CREATE TABLE ##Array (RowNum INT NOT NULL, Val AS VARCHAR(10)) -- See ## prefix that means a global temp table 

INSERT #Array (RowNum, Val) VALUES (1, 'A')
INSERT #Array (RowNum, Val) VALUES (2, 'BBB')

要查看在SQL Server中存储/使用数组的所有选项的完整列表,请参阅Erland Sommarskog撰写的以下文章 http://www.sommarskog.se/arrays-in-sql.html。我个人的选择是使用XML或@table变量。

[3]关于当前问题提出的方法:这很糟糕。假设我们必须模拟一个数组,那么应该存储来自该数组的值(如果我们在行中的单个列中使用表/ ## temp tables / @table变量)(参见上面的示例)和不在不同的列(Col1,Col2等)。

我的建议是阅读Erland Sommarskog的文章,并为您的方案选择合适的解决方案。

答案 1 :(得分:1)

我很遗憾地说,但你发布的代码是完全不合理的 你应该简单地改变你的表结构只包含2列 - 一个用于索引,另一个用于值:

,而不是乱用动态SQL。
CREATE TABLE aaa (
    id int identity(1, 1),
    val char(40)
)

INSERT INTO aaa VALUES
('aaaa'),
('qqqq'),
('eeee')

SELECT val
FROM aaa
WHERE Id = 3

答案 2 :(得分:0)

您可以使用sp_executesql OUTPUT参数来指定标量结果:

IF OBJECT_ID('tempdb..aaa') IS NOT NULL DROP TABLE aaa
CREATE TABLE aaa (
    #1 char(40),
    #2 char(40),
    #3 char(40)
);
INSERT INTO aaa VALUES ('aaaa','qqqq','eeee');
DECLARE @sql nvarchar(40);
DECLARE @sqlStatement nvarchar(MAX);
DECLARE @var varchar(40)='#3';
SET @sqlStatement = '(SELECT '+@var +' FROM aaa)';
EXEC sp_executesql @sqlStatement, N'@sql varchar(40) OUTPUT', @sql = @sql OUTPUT;
PRINT @sql;

我认为对结果使用名为@sql的变量有点令人困惑。

答案 3 :(得分:0)

您可以创建临时表(或表变量)并将动态sql的结果插入。

create table #tmpResult (res CHAR(40));

declare @sql varchar(40);
declare @var varchar(40)='#3';
set @sql= '(select '+@var +' from aaa)';
insert #tmpResult
exec (@sql)

select * from  #tmpResult --you can easily fill @sql variable from here

或者您甚至可以更改动态sql以包含此插入内容:

create table #tmpResult (res CHAR(40));

declare @sql varchar(40);
declare @var varchar(40)='#3';
set @sql= 'insert #tmpResult select '+@var +' from aaa';
exec (@sql)

select * from  #tmpResult