我必须重构和记录许多foo.sql
查询,这些查询将由数据库技术支持团队共享(针对客户配置等)。每个客户都有自己的服务器和数据库的票证类型经常出现,但其他方面的架构是相同的。
当前无法选择存储过程。我正在讨论是使用动态还是使用SQLCMD,因为我在SQL Server上有些新手,所以我也没有使用太多。
我觉得SQLCMD脚本对我来说绝对看起来更“干净”,并且更易于阅读和根据需要对查询进行较小的更改,但同时也迫使用户启用SQLCMD模式。由于使用字符串操作编写查询会导致语法高亮丢失,因此动态处理更加困难。
这些正在使用Management Studio 2012(SQL版本2008R2)进行编辑和运行。每种方法的优缺点是什么,或者一种方法或另一种方法的某些SQL Server“最佳实践”是什么?其中一个比另一个更“安全”吗?
动态示例:
declare @ServerName varchar(50) = 'REDACTED';
declare @DatabaseName varchar(50) = 'REDACTED';
declare @OrderIdsSeparatedByCommas varchar(max) = '597336, 595764, 594594';
declare @sql_OrderCheckQuery varchar(max) = ('
use {@DatabaseName};
select
-- stuff
from
{@ServerName}.{@DatabaseName}.[dbo].[client_orders]
as "Order"
inner join {@ServerName}.{@DatabaseName}.[dbo].[vendor_client_orders]
as "VendOrder" on "Order".o_id = "VendOrder".vco_oid
where "VendOrder".vco_oid in ({@OrderIdsSeparatedByCommas});
');
set @sql_OrderCheckQuery = replace( @sql_OrderCheckQuery, '{@ServerName}', quotename(@ServerName) );
set @sql_OrderCheckQuery = replace( @sql_OrderCheckQuery, '{@DatabaseName}', quotename(@DatabaseName) );
set @sql_OrderCheckQuery = replace( @sql_OrderCheckQuery, '{@OrderIdsSeparatedByCommas}', @OrderIdsSeparatedByCommas );
print (@sql_OrderCheckQuery); -- For debugging purposes.
execute (@sql_OrderCheckQuery);
SQLCMD示例:
:setvar ServerName "[REDACTED]";
:setvar DatabaseName "[REDACTED]";
:setvar OrderIdsSeparatedByCommas "597336, 595764, 594594"
use $(DatabaseName)
select
--stuff
from
$(ServerName).$(DatabaseName).[dbo].[client_orders]
as "Order"
inner join $(ServerName).$(DatabaseName).[dbo].[vendor_client_orders]
as "VendOrder" on "Order".o_id = "VendOrder".vco_oid
where "VendOrder".vco_oid in ($(OrderIdsSeparatedByCommas));
use
语句可能会被忽略,因为无论如何在此特定脚本期间范围不会更改。我有少数用例,其中会有跨服务器搜索,但这可能超出了本文的范围。
use ...
您的脚本的目的是什么?正确执行后续查询是否重要?我问是因为更改当前数据库是否是查询的预期结果之一,所以动态SQL版本只会在动态查询的范围(而不是外部范围)中更改它,这与SQLCMD变体不同(当然,只有一个范围)。