我创建了一个存储过程,如果表存在于数据库中,它将删除该表.使用EXEC运行存储过程时,我收到以下错误:
消息203,级别16,状态2,过程sp_DropIfExists,行13名称'IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N'table_name')AND type =(N'U'))DROP TABLE [table_name ]'不是有效的标识符.
但是,如果我将生成的T-SQL复制并粘贴到管理工作室,它似乎运行正常.有人能解释为什么这是无效的吗?修复会很好,但我真的是在主要为什么之后,尽管如此会更好!提前致谢.
ALTER PROCEDURE [dbo].[sp_DropIfExists](@tableName VARCHAR(255))
AS
BEGIN
SET NOCOUNT ON;
DECLARE @SQL VARCHAR(MAX);
SET @SQL = 'IF EXISTS(SELECT 1 FROM sys.objects WHERE OBJECT_ID = OBJECT_ID(N''' + @tableName + ''') AND type = (N''U'')) DROP TABLE [' + @tableName + ']'
PRINT @SQL;
EXEC @SQL;
END
Run Code Online (Sandbox Code Playgroud) 我目前有一个链接服务器,我在存储过程中查询.我现在的查询工作得很好但是这个查询需要为我拥有的每个代码分支进行更改.我想知道什么是最好的方法来驱动我在跨服务器查询中调用的数据库名称.
例如:服务器A有一个到服务器B的链接.服务器A包含3个数据库.SRV_A.DB1_DEV,SRV_A.DB2_Trunk,SRV_A.DB3_Prod每个都链接到它们的服务器B对应... SRV_B.DB1_DEV,SRV_B.DB2_Trunk,SRV_B.DB3_Prod
服务器A上的每个数据库都具有相同的存储过程.在sproc中唯一改变的是跨服务器选择.所以SRV_A.DB1_Dev在sproc中有一个select:
SELECT foo FROM [SRV_B].[DB1_DEV].[foo_table] WHERE bar = 1
Run Code Online (Sandbox Code Playgroud)
而主干分支上的存储过程将是
SELECT foo FROM [SRV_B].[DB2_Trunk].[foo_table] WHERE bar = 1
Run Code Online (Sandbox Code Playgroud)
由于我希望有一个VS项目将数据库部署到所提到的每个分支,我希望能够动态填写数据库名称.我提出的解决方案是使用CHARINDEX函数进行一系列IF检查,然后使用动态SQL创建查询,如下所示:
DECLARE @dSql NVARCHAR(4000);
DECLARE @databaseName NVARCHAR(100) = DB_NAME();
DECLARE @tableName NVARCHAR(100);
IF SELECT CHARINDEX('Dev', @databaseName, 0)
SET @tableName = '[SRV_B].[DB1_DEV].[foo_table]
...Same if & set for Trunk
...Same if & set for Prod
SET @dSql = 'DECLARE @retID INT;SELECT foo FROM ' + @tableName
+ ' WHERE bar = 1';SET @retID = SELECT SCOPE_IDENTITY()'
EXEC(@dSQL);
Run Code Online (Sandbox Code Playgroud)
我不得不想象有一个更好的解决方案,如果有人可以帮助我,我会非常感激.如果通过一些外线拍摄这是最好的方式让我知道.
谢谢,詹姆斯