使用EXEC模拟Sql Server GO语句

时间:2017-11-09 22:05:57

标签: sql-server

我有代码,给出带有GO语句的SQL,使用以下逻辑将其转换为单个SQL语句,而不使用GO语句:

"EXEC('" + sql.Replace("'", "''").Replace("GO", "');EXEC('") + "')"

当然,实际逻辑有点健壮,但精神是一样的。

但是,GO不等同于EXEC。例如,以下代码有效:

IF OBJECT_ID('tempdb..#tmp') IS NOT NULL DROP TABLE #tmp
SELECT 1 A INTO #tmp
GO
SELECT * FROM #tmp

并返回:

enter image description here

但是,带有EXEC的版本不起作用:

EXEC('
IF OBJECT_ID(''tempdb..#tmp'') IS NOT NULL DROP TABLE #tmp
SELECT 1 A INTO #tmp
');EXEC('
SELECT * FROM #tmp
')

结果是:

enter image description here

有没有办法消除GO语句,以便可以使用一个SQL命令在ADO.NET中运行生成的SQL?

编辑1

我很抱歉,如果我的帖子让一些人感到困惑。我不是在寻找创建表UDT或临时表的方法。

我正在使用ADO.NET与Sql Server数据库通信。具体来说,我使用SqlCommand类在服务器上运行SQL。如果该SQL包含GO语句,则它是无效的Sql,因为GO不是Sql关键字,它用于在SSMS中运行时分隔批处理。因此,有两种方法可以解决它:

  1. 使用GO关键字作为分隔符拆分SQL并分别运行每个块。因此,如果有N个批次,那么将有N SqlCommand个API调用来运行相应的批次。
  2. 如我所述,将GO替换为EXEC。在这种情况下,只有一个SqlCommand,但EXECGO不相等。
  3. 所以,我问的是,在向Sql Server发出一个GO API调用时,是否还有另一种方法可以尊重ADO.NET中的SqlCommand语句。

2 个答案:

答案 0 :(得分:1)

简短回答 - 不。如果脚本被编写为多个批次,那么必须将它们作为多个批次执行。你无法模拟"批量分离在一个批处理执行中的效果,而不会大幅改变使用的tsql - 这将涉及写入代码来解释然后重写脚本。

答案 1 :(得分:0)

动态查询不会将临时表存储在临时数据库中,因此您无需删除它。

IN SSMS

试试这个,应该给你你想要的东西。

EXEC('SELECT 1 A INTO #tmp;
    SELECT * FROM #tmp');

但我认为您倾向于使用用户定义的表类型 https://technet.microsoft.com/en-us/library/bb522526(v=sql.105).aspx

它使用内存表,不占用空间,不需要删除。