在 SQL Azure 中使用临时表

发布于 2024-11-29 03:53:32 字数 1026 浏览 0 评论 0原文

我正在编写一个查询来旋转表元素,其中列名称是动态生成的。

SET @query = N'SELECT STUDENT_ID, ROLL_NO, TITLE, STUDENT_NAME, EXAM_NAME, '+
            @cols +
            ' INTO ##FINAL 
            FROM
            (
                SELECT  *
                FROM #AVERAGES
                UNION 
                SELECT  *
                FROM #MARKS 
                UNION
                SELECT  *
                FROM #GRACEMARKS
                UNION
                SELECT  *
                FROM #TOTAL
                ) p
                PIVOT
                (
                MAX([MARKS])
                FOR SUBJECT_ID IN
                ( '+
                @cols +' )
            ) AS FINAL
            ORDER BY STUDENT_ID ASC, DISPLAYORDER ASC, EXAM_NAME ASC;'

EXECUTE(@query) 

select * from ##FINAL 

此查询在我的本地数据库中正常工作,但在 SQL Azure 中不起作用,因为那里不允许全局临时表。

现在,如果我在本地数据库中将 ##FINAL 更改为 #FINAL,但它会给我错误:

对象名称“#FINAL”无效。

我该如何解决这个问题?

I am writing a query to pivoting table elements where column name is generated dynamically.

SET @query = N'SELECT STUDENT_ID, ROLL_NO, TITLE, STUDENT_NAME, EXAM_NAME, '+
            @cols +
            ' INTO ##FINAL 
            FROM
            (
                SELECT  *
                FROM #AVERAGES
                UNION 
                SELECT  *
                FROM #MARKS 
                UNION
                SELECT  *
                FROM #GRACEMARKS
                UNION
                SELECT  *
                FROM #TOTAL
                ) p
                PIVOT
                (
                MAX([MARKS])
                FOR SUBJECT_ID IN
                ( '+
                @cols +' )
            ) AS FINAL
            ORDER BY STUDENT_ID ASC, DISPLAYORDER ASC, EXAM_NAME ASC;'

EXECUTE(@query) 

select * from ##FINAL 

This query works properly in my local database, but it doesn't work in SQL Azure since global temp tables are not allowed there.

Now if i change ##FINAL to #FINAL in my local database, but it gives me error as

Invalid object name '#FINAL' .

How can I resolve this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

演多会厌 2024-12-06 03:53:32

好吧,说完我觉得不行,也许我还有办法。虽然它很丑。希望您可以使用下面的示例并将其适应您的查询(没有您的架构和数据,对我来说尝试编写它太棘手):

declare @cols varchar(max)
set @cols = 'object_id,schema_id,parent_object_id'

--Create a temp table with the known columns
create table #Boris (
    ID int IDENTITY(1,1) not null
)
--Alter the temp table to add the varying columns. Thankfully, they're all ints.
--for unknown types, varchar(max) may be more appropriate, and will hopefully convert
declare @tempcols varchar(max)
set @tempcols = @cols
while LEN(@tempcols) > 0
begin
    declare @col varchar(max)
    set @col = CASE WHEN CHARINDEX(',',@tempcols) > 0 THEN SUBSTRING(@tempcols,1,CHARINDEX(',',@tempcols)-1) ELSE @tempcols END
    set @tempcols = CASE WHEN LEN(@col) = LEN(@tempcols) THEN '' ELSE SUBSTRING(@tempcols,LEN(@col)+2,10000000) END
    declare @sql1 varchar(max)
    set @sql1 = 'alter table #Boris add [' + @col + '] int null'
    exec (@sql1)
end

declare @sql varchar(max)
set @sql = 'insert into #Boris (' + @cols + ') select ' + @cols + ' from sys.objects'
exec (@sql)

select * from #Boris

drop table #Boris

它们的关键是在外部范围中创建临时表,然后内部作用域(在 EXEC 语句内运行的代码)可以访问相同的临时表。上面的代码适用于 SQL Server 2008,但我没有 Azure 实例可供使用,因此没有在那里进行测试。

Okay, after saying I didn't think it could be done, I might have a way. It's ugly though. Hopefully, you can play with the below sample and adapt it to your query (without having your schema and data, it's too tricky for me to attempt to write it):

declare @cols varchar(max)
set @cols = 'object_id,schema_id,parent_object_id'

--Create a temp table with the known columns
create table #Boris (
    ID int IDENTITY(1,1) not null
)
--Alter the temp table to add the varying columns. Thankfully, they're all ints.
--for unknown types, varchar(max) may be more appropriate, and will hopefully convert
declare @tempcols varchar(max)
set @tempcols = @cols
while LEN(@tempcols) > 0
begin
    declare @col varchar(max)
    set @col = CASE WHEN CHARINDEX(',',@tempcols) > 0 THEN SUBSTRING(@tempcols,1,CHARINDEX(',',@tempcols)-1) ELSE @tempcols END
    set @tempcols = CASE WHEN LEN(@col) = LEN(@tempcols) THEN '' ELSE SUBSTRING(@tempcols,LEN(@col)+2,10000000) END
    declare @sql1 varchar(max)
    set @sql1 = 'alter table #Boris add [' + @col + '] int null'
    exec (@sql1)
end

declare @sql varchar(max)
set @sql = 'insert into #Boris (' + @cols + ') select ' + @cols + ' from sys.objects'
exec (@sql)

select * from #Boris

drop table #Boris

They key is to create the temp table in the outer scope, and then inner scopes (code running within EXEC statements) have access to the same temp table. The above worked on SQL Server 2008, but I don't have an Azure instance to play with, so not tested there.

素手挽清风 2024-12-06 03:53:32

如果您创建临时表,则它在 spid 中执行的动态 sql 中可见,如果您在动态 sql 中创建表,则它在外部不可见。

有一个解决方法。您可以创建存根表并在动态 sql 中更改它。它需要一些字符串操作,但我已经使用此技术为 tsqlunit 生成动态数据集。

CREATE TABLE #t1 
(
    DummyCol int
)

EXEC(N'ALTER TABLE #t1 ADD  foo INT')

EXEC ('insert into #t1(DummyCol, foo)
VALUES(1,2)')

EXEC ('ALTER TABLE #t1 DROP COLUMN DummyCol')

select *from #t1 

If you create a temp table, it's visible from dynamic sql executed in your spid, if you create the table in dynamic sql, it's not visible outside of that.

There is a workaround. You can create a stub table and alter it in your dynamic sql. It requires a bit of string manipulation but I've used this technique to generate dynamic datasets for tsqlunit.

CREATE TABLE #t1 
(
    DummyCol int
)

EXEC(N'ALTER TABLE #t1 ADD  foo INT')

EXEC ('insert into #t1(DummyCol, foo)
VALUES(1,2)')

EXEC ('ALTER TABLE #t1 DROP COLUMN DummyCol')

select *from #t1 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文