【问题标题】:How to execute store procedure for another DB?如何为另一个数据库执行存储过程?
【发布时间】:2011-11-21 05:13:36
【问题描述】:

我有一个存储过程,应该能够在我的 MS Sql Server 上的任何数据库的任何表上执行。大多数 EXEC 和 USE 语句的组合没有产生任何结果。这是存储过程:

CREATE PROCEDURE [dbo].[usp_TrimAndLowerCaseVarcharFields]
(
    @Database VARCHAR(200),
    @TableSchema VARCHAR(200),
    @TableName VARCHAR(200)
)
AS
BEGIN
    DECLARE @sSql VARCHAR(MAX)

    SET @Database = '[' + @Database + ']'
    SET @sSql = ''

    -- Create first part of a statement to update all columns that have type varchar
    SELECT @sSql = @sSql + COLUMN_NAME + ' = LOWER(RTRIM(' + COLUMN_NAME + ')), ' 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE DATA_TYPE = 'varchar'
    AND TABLE_CATALOG = @Database
    AND TABLE_SCHEMA = @TableSchema
    AND TABLE_NAME = @TableName

    SET @sSql = 'UPDATE ' + @Database + '.' + @TableSchema + '.' + @TableName + ' SET ' + @sSql

    -- Delete last two symbols (', ')
    SET @sSql = LEFT(@sSql, LEN(@sSql) - 1)

    EXEC(@sSql)
END

请告诉我在 [OtherDB].[TargetTable] 上执行它需要做什么。

【问题讨论】:

    标签: sql sql-server stored-procedures linked-server


    【解决方案1】:

    您可以完全限定表和存储过程。换句话说,您可以这样做:

    UPDATE [OtherDB].[Schema].[targetTable] SET ...
    

    看来你已经在你的过程中这样做了。

    您还可以使用完全限定名称执行存储过程 - 例如

    EXEC [OtherDB].[dbo].[usp_TrimAndLowerCaseVarcharFields]
    

    老实说,您的 proc 看起来不错,您是否收到任何错误消息?如果是这样,请发布它们。此外,请确保您的用户有权访问其他数据库。

    【讨论】:

    • EXEC 还支持AT 对链接服务器运行命令。
    • 和 4 部分命名,例如exec [linkedserver].[database].[schema].[proc]
    【解决方案2】:

    您使用的查询中的表名错误,它正在查找相同的数据库,但您确实需要从不同的数据库中查找。所以查询如下:

    SELECT @sSql = @sSql + COLUMN_NAME + ' = LOWER(RTRIM(' + COLUMN_NAME + ')), ' 
    FROM [TargetDB].INFORMATION_SCHEMA.COLUMNS 
    WHERE DATA_TYPE = 'varchar'
    AND TABLE_CATALOG = @Database
    AND TABLE_SCHEMA = @TableSchema
    AND TABLE_NAME = @TableName
    
    -- [TargetDB] = @Database
    

    TargetDB 将与您传递的数据库 (@Database) 相同

    如果你想动态使用 [TargetDB] 那么你需要生成 sql(@sSql) 并执行 sql 字符串。

    【讨论】:

      【解决方案3】:

      在这种情况下,我建议在 SQL Server 中使用 2 个 sp:

      • sp_MSforeachtable

      • sp_MSforeachdb

      更多信息,请阅读here中的文章。 希望对您有所帮助。

      exec @RETURN_VALUE=sp_MSforeachtable @command1, @replacechar, @command2, 
        @command3, @whereand, @precommand, @postcommand
      
      exec @RETURN_VALUE = sp_MSforeachdb @command1, @replacechar, 
        @command2, @command3, @precommand, @postcommand
      

      完整的脚本:

      declare @DatabaseName varchar(max), @DatabaseCharParam nchar(1) 
      declare @TableSchema varchar(max) 
      declare @TableName varchar(max), @TableCharParam nchar(1) 
      set @DatabaseName='DATABASENAME'; set @DatabaseCharParam='?'
      set @TableSchema='dbo'
      set @TableName='TABLENAME'; set @TableCharParam='$'
      
      
       -- Exemple Script to execute in each table in each database
       -- Create first part of a statement to update all columns that have type varchar
          DECLARE @sSql VARCHAR(MAX)
          set @sSql=''
          SELECT @sSql = isnull(@sSql,'') + COLUMN_NAME + ' = LOWER(RTRIM(' + COLUMN_NAME + ')),' 
          FROM INFORMATION_SCHEMA.COLUMNS 
          WHERE DATA_TYPE = 'varchar'
          AND TABLE_CATALOG = @DatabaseName
          AND TABLE_SCHEMA = @TableSchema
          AND TABLE_NAME = @TableName
      
      
      
      declare @EachTablecmd1 varchar(2000)
      --Prepare @EachTablecmd1 the script to execution in each table using sp_MSforeachtable (ATENTION: @Command1 are limited to varchar(2000) )
          --in sp_MSforeachtable @TableCharParam will be subtituted with owner i.e:[dbo].[TABLENAME]
      set @sSql='update '+@TableCharParam+' set '+ left(@sSql,LEN(@sSql)-1) 
      set @EachTablecmd1='if '''''+ @TableCharParam +'''''=''''['+@TableSchema+'].['+@TableName+']'''' '+@sSql
          --i.e.: if 'table1'='table1' update table1 set column1=LOWER(RTRIM(column1)),....
      
      -- the @sSql for each table in a database
      set @sSql ='exec sp_MSforeachtable @command1='''+@EachTablecmd1+''' ,@replacechar='''+@TableCharParam+''''
      
      
      
      declare @EachBDcmd1 varchar(2000)
      --Prepare the execution to each database using sp_MSforeachdb (ATENTION: @Command1 are limited to varchar(2000) )
      set @EachBDcmd1='if '''+@DatabaseCharParam+'''='''+@DatabaseName+''' '+ @sSql
      --print @EachBDcmd1
      exec sp_MSforeachdb @command1=@EachBDcmd1,@replacechar=@DatabaseCharParam
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多