Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何为另一个数据库执行存储过程?_Sql_Sql Server_Stored Procedures_Linked Server - Fatal编程技术网

Sql 如何为另一个数据库执行存储过程?

Sql 如何为另一个数据库执行存储过程?,sql,sql-server,stored-procedures,linked-server,Sql,Sql Server,Stored Procedures,Linked Server,我有一个存储过程,它应该能够在我的MS Sql Server上任何数据库的任何表上执行。EXEC和USE语句的大多数组合并没有产生任何结果。以下是存储过程: CREATE PROCEDURE [dbo].[usp_TrimAndLowerCaseVarcharFields] ( @Database VARCHAR(200), @TableSchema VARCHAR(200), @TableName VARCHAR(200) ) AS BEGIN DECLARE

我有一个存储过程,它应该能够在我的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]上执行它需要做什么。

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

UPDATE [OtherDB].[Schema].[targetTable] SET ...
看起来你已经在你的进程中这样做了

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

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

老实说,您的进程看起来很好,您是否收到任何错误消息?如果有的话,请把它们寄出去。另外,请确保您的用户有权访问其他数据库。

您使用的查询中的表名是错误的,它正在查找同一个数据库,但您确实需要从不同的数据库中查找。因此,查询将如下所示:

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字符串。

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

  • sp_MSforeachtable

  • sp_MSforeachdb

有关更多信息,请阅读中的文章。 希望这有帮助

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

EXEC
还支持
AT
对链接服务器运行命令,以及4部分命名,例如EXEC[linkedserver].[database].[schema].[proc]