Je dois refactoriser et documenter un certain nombre de foo.sql
requêtes qui seront partagées par une équipe de support technique DB (pour les configurations client et des choses comme ça). Il existe des types de tickets qui viennent régulièrement lorsque chaque client a ses propres serveurs et bases de données, mais sinon le schéma est le même à tous les niveaux.
Les procédures stockées ne sont pas une option à l'heure actuelle. Je suis en train de débattre de l'utilisation de Dynamic ou SQLCMD, je n'en ai pas beaucoup utilisé car je suis un peu nouveau chez SQL Server.
Les scripts SQLCMD Je me sens vraiment "plus" propre pour moi, plus facile à lire et à apporter de petites modifications aux requêtes selon les besoins, mais force également l'utilisateur à activer le mode SQLCMD. La dynamique est plus difficile car la mise en évidence de la syntaxe est une perte due à l'écriture de la requête à l'aide de la manipulation de chaînes.
Ceux-ci sont en cours d'édition et exécutés à l'aide de Management Studio 2012, SQL version 2008R2. Quels sont les avantages / inconvénients de l'une ou l'autre méthode, ou certaines des "meilleures pratiques" de SQL Server sur une méthode ou l'autre? L'un d'eux est-il "plus sûr" que l'autre?
Exemple dynamique:
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);
Exemple 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
instruction pourrait probablement être omise, car la portée ne sera pas modifiée de toute façon pendant ce script particulier. J'ai un petit nombre de cas d'utilisation où il y aura des recherches inter-serveurs mais qui pourraient être au-delà de la portée de cet article.
use ...
votre script? Est-ce important pour l'exécution correcte de la requête suivante? Je demande parce que si la modification de la base de données actuelle est l'un des résultats attendus de votre requête, la version SQL dynamique ne la modifiera que dans la portée de la requête dynamique, pas dans la portée externe, contrairement à la variation SQLCMD (qui, de n’a qu’une seule portée).