Dan*_*ars 10 t-sql sql-server-2008-r2
在 SQL Server 中创建存储过程时,您可以引用不存在的表。但是,如果该表确实存在,那么您在该过程中引用的任何列都必须存在于该表中(延迟名称解析)。
是否可以指示 SQL Server 推迟过程中引用的所有表的名称解析,而不管它们是否存在?我确实希望保留一般语法检查,因此即使可能,将存储过程定义破解到系统表中也不是一种选择。
我希望我的要求做到这一点可能看起来有点怪异,所以这里的一些背景:我自动从C#编写的应用程序生成表定义和存储过程,这是非常困难的,我改变代码顺序进行更改为SQL需求他们。我的代码“保证”架构在事务中是一致的,但目前我不能保证在定义引用它们的存储过程之前定义表列。
下面是 C# 创建的 SQL 的规范示例,它“说明”了我试图解决的问题。
--Say this table already exists.
CREATE TABLE myTable
(
a NVARCHAR(MAX)
)
GO
--My C# code creates something like this
BEGIN TRAN
GO
--the stored procedure gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
SELECT a,b FROM myTable
END
--then the table update
ALTER TABLE myTable
ADD b nvarchar(MAX)
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)
我有可能在 C# 代码中修复这个问题,但我希望能有一个简单的“魔法”调整我可以拉入 SQL。这将为我节省很多时间。
不。
打字我真的很内疚,但遗憾的是没有。那是我第一次听说这个用例,它完全有道理。最好在https://feedback.azure.com/forums/908035-sql-server上提交请求,你的孙子们就能做到。;-)
以防万一您仍然感兴趣,您可以采用一种潜在的解决方法。这是更新后的代码,它将#deferResolution
临时表引入过程中的每个查询。因为临时表只在运行时存在,所以即使在myTable
.
#deferResolution
由于查询优化器可以证明这WHERE NOT EXISTS
总是评估为真的方式,您甚至会为过程中的每个语句获得相同的执行计划(不引用表)。
综上所述,这是一个可怕的黑客攻击,主要是为了知识分子的兴趣,并且可能会出现崩溃的边缘情况。正如 Aaron 所提到的,您最好按照正确的顺序进行所有架构更改。
--Say this table already exists.
CREATE TABLE myTable
(
a NVARCHAR(MAX)
)
GO
--My C# code creates something like this
BEGIN TRAN
GO
--the sproc gets generated first.
CREATE PROCEDURE mySproc
AS
BEGIN
CREATE TABLE #deferResolution (dummy INT NOT NULL)
SELECT a,b FROM myTable WHERE NOT EXISTS (SELECT * FROM #deferResolution WHERE 0=1)
END
--then the table update
ALTER TABLE myTable
ADD b nvarchar(MAX)
COMMIT TRAN
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3300 次 |
最近记录: |