我正在尝试创建一个具有动态列数的临时表:
set @cmd = ' SELECT * into #temp3 from
(
select * from sometable
) x pivot
(
max(buildrate)
for name in ('+ @columns +')
) as y '
execute(@cmd);
select * from #temp3 left join performed in an elegant way...
我需要在其他处理中使用该表中的内容。
有没有合理的方法可以做到这一点?
答案 0 :(得分:3)
一种解决方法是使用全局临时表:
SET @cmd = ' SELECT * INTO ##temp3 FROM
(
select * from sometable
) x pivot
(
max(buildrate)
for name in ('+ @columns +')
) as y '
EXECUTE(@cmd);
SELECT *
INTO #temp3
FROM ##temp3;
DROP TABLE ##temp3;
SELECT *
FROM JOIN #temp3
LEFT ...;
普通的本地临时表不起作用,因为Dynamic SQL会创建新的上下文。该表位于该上下文中,并且在执行代码时将不再存在,因此您无法在Dynamic-SQL外部使用它。
答案 1 :(得分:0)
基于@Ocaso Protal评论,我创建了这个
-- create global temporary table with timestamp to prevent multiple user collision
DECLARE @timestamp NVARCHAR(255) = REPLACE(REPLACE(REPLACE(REPLACE(CONVERT(NVARCHAR(23), GETDATE(), 121),'-',''),' ',''),':',''),'.','')
DECLARE @temp NVARCHAR(255) = '##temp_'+@timestamp
SET @query = 'CREATE TABLE ' + @temp + ' (RowName NVARCHAR(255), ' + @outputQueryColumns + ')'
EXECUTE sp_executesql @query
-- working with temporary table whether in procedure or in dynamic sql
-- delete global temporary table
SET @query = 'DROP TABLE ' + @temp
EXECUTE sp_executesql @query
答案 2 :(得分:0)
我创建此脚本来测试动态临时表。
我根据https://celedonpartners.com/blog/sql-server-how-to-a-create-temp-table-with-dynamic-column-names/中的帖子
希望这会有所帮助。
-- create and populate table
DROP TABLE dbo.sometable
GO
CREATE TABLE dbo.sometable(
daterate datetime,
name varchar(100),
buildrate decimal(10,3),
)
GO
DECLARE @COUNT INT
SET @COUNT = 0
WHILE @COUNT < 1000
BEGIN
IF (CAST(RAND() * 2 AS INT) % 2) = 1
BEGIN
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()), 'Jeff', RAND() * 25.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Andrew', RAND() * 25.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Mary', RAND() * 25.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Carl', RAND() * 25.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Zack', RAND() * 25.0)
END
ELSE
BEGIN
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Jack', RAND() * 50.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Mag', RAND() * 50.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Kim', RAND() * 50.0)
INSERT INTO dbo.sometable(daterate, name, buildrate) values(DATEADD(DAY, RAND() * -180, GETDATE()),'Suse', RAND() * 50.0)
END
SET @COUNT = @COUNT + 1
END
GO
-- execute query with the created table
DECLARE @columns VARCHAR(MAX)
, @columns_name varchar(max)
, @sql varchar(max)
IF OBJECT_ID('tempdb..#temp3') != 0
DROP TABLE #temp3
SELECT
@columns = COALESCE(@columns + ', ', '') + '[' + name + '] float'
,@columns_name = COALESCE(@columns_name + ', ', '') + '[' + name + ']'
FROM (SELECT DISTINCT NAME FROM sometable) VW
order by name
CREATE TABLE #temp3(
daterate varchar(10)
)
EXEC('alter table #temp3 add ' + @columns)
SET @sql = 'insert into #temp3
select * from
(
select name, buildrate, right(convert(varchar(10), daterate, 103), 7) as daterate from sometable
) x pivot
(
max(buildrate)
for name in ('+ @columns_name +')
) as y '
EXEC(@sql)
SELECT * FROM #temp3