select * from INFORMATION_SCHEMA.TABLES;
select * from INFORMATION_SCHEMA.COLUMNS;
select * from INFORMATION_SCHEMA.ROUTINES;
select * from INFORMATION_SCHEMA.PARAMETERS;
CREATE PROCEDURE DM_TCM_TO_COMCARE
@FROM_DB varchar(100) = '',
@TO_DB varchar(100) = ''
AS
BEGIN
--CHECK INPUT VARIABLES
DROP SYNONYM dbo.From_TableA
SET @SQL_SCRIPT = 'CREATE SYNONYM dbo.From_TableA FOR ['+@FROM_DB+'].[dbo].[TableA]'
exec (@SQL_SCRIPT)
DROP SYNONYM dbo.To_TableB
SET @SQL_SCRIPT = 'CREATE SYNONYM dbo.To_TableB FOR ['+@TO_DB+'].[dbo].[TableB]'
exec (@SQL_SCRIPT)
select * from dbo.From_TableA
select * from dbo.To_TableB
insert into dbo.To_TableB
select * from dbo.From_TableA where 1 = 1
-- etc
END
GO
7条答案
按热度按时间yptwkmov1#
如果要这样动态地执行,就必须使用动态sql。这意味着您要在该数据库的上下文中执行的任何操作,也需要包含在动态sql语句中。
i、 e.假设您要列出maindb中的所有表:
这不起作用,因为use语句位于不同的上下文中—一旦execute运行,以下select将不会在同一上下文中运行,因此也不会在maindb中运行(除非连接已设置为maindb)
所以你需要做:
当然,您需要非常小心地使用sql注入,为此,我向您指出barry答案中的链接。
为了防止sql注入,还可以使用quotename()函数,它将参数 Package 在方括号中:
vmpqdwk32#
如果在ssms中运行脚本,可以使用sqlcmd模式(在查询菜单下)为数据库名称编写变量脚本。
mec1mxoz3#
改用同义词
而不是动态sql来做等价的
USE @Database
,我可以提出一些“预处理动态sql”对您来说是更好的解决方案吗?当然,这取决于为什么需要动态use语句。我假设您从一开始就不能使用连接字符串中的正确数据库(这是处理此问题的最佳方法)。我建议的动态sql是从为要引用的每个对象创建同义词开始:
然后在存储过程中或者在动态use语句之后您想做的任何事情中,只需参考
dbo.CustomName
.为了方便地切换,您可以创建一个小的基础设施。用同义词别名和它们将Map到的对象构建一个表。创建一个存储过程来读取此表并运行动态sql来更新同义词。
当您需要切换时,运行该sp,它将穿透您需要的所有对象并重新链接它们。
警告
如果需要不同的进程通过同义词同时访问不同的数据库,则此策略将不起作用。那样的话,你最好用别的方法。
请记住,您仍然可以通过一些聪明的方法避免动态sql。例如,与其将要运行的sp放在主数据库中并让它动态地对每个子数据库执行操作,不如将sp放在每个子数据库中,然后调用每个sp。
cunj1qz14#
如果您需要作为部署过程或某个后端过程的一部分来执行此操作,而不是由用户启动某个操作,那么您可以选择将所有内容都放入这样的动态语句中
通过使用sqlcmd实用程序和您最喜欢的脚本程序,您可以走老路。我推荐powershell,但对于这个示例,我将使用经典的dos批处理。
假设您的文件c:\input.sql如下所示
您可以在多个数据库上执行input.sql,方法是将以下文件放入批处理文件c:\test.bat(该批处理假定与input.sql位于同一目录中)
c:\测试.bat
然后你可以通过
c:>测试.bat
这种方法的优点是
您可以像平常一样开发input.sql
它也没有execute所具有的varchar限制。。
许多选项与脚本powershell,vbs,ms-dos批处理,shell执行
很多sqlcmd选项(输出文件、超时等)
w8f9ii695#
只要你相信
@DatabaseName
不包含;DROP DATABASE MyDB
:)pokxtpni6#
我发现synonym和exec dynamic sql的混合是我唯一能做的事情(尤其是作为具有多个数据库的存储过程的一部分)。这是一个简化的版本,它实现了从变量名查询数据库。
fkaflof67#
您必须使用动态sql来实现这一点。
在您开始探索动态sql之前,我建议您阅读这篇优秀的文章http://www.sommarskog.se/dynamic_sql.html