Tengo que refactorizar y documentar una serie de foo.sql
consultas que serán compartidas por un equipo de soporte técnico de DB (para configuraciones de clientes y cosas por el estilo). Hay tipos de tickets que vienen regularmente donde cada cliente tiene sus propios servidores y bases de datos, pero de lo contrario el esquema es el mismo en todos los ámbitos.
Los procedimientos almacenados no son una opción en este momento. Estoy debatiendo si usar dinámico o SQLCMD, no he usado mucho ya que soy un poco nuevo en SQL Server.
Las secuencias de comandos SQLCMD definitivamente me parecen "más limpias", más fáciles de leer y realizar pequeños cambios en las consultas según sea necesario, pero también obliga al usuario a habilitar el modo SQLCMD. La dinámica es más difícil ya que el resaltado de sintaxis es pérdida debido a que la consulta se escribe utilizando la manipulación de cadenas.
Estos se están editando y ejecutando usando Management Studio 2012, SQL versión 2008R2. ¿Cuáles son algunos de los pros / contras de cualquiera de los métodos, o algunas de las "mejores prácticas" de SQL Server en un método u otro? ¿Es uno de ellos "más seguro" que el otro?
Ejemplo dinámico:
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);
Ejemplo de 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
declaración probablemente podría omitirse, ya que el alcance no se cambiará durante este script en particular de todos modos. Tengo una pequeña cantidad de casos de uso en los que habrá búsquedas entre servidores, pero eso podría estar fuera del alcance de esta publicación.
use ...
tu guión? ¿Es importante para la correcta ejecución de la consulta posterior? Lo pregunto porque si cambiar la base de datos actual es uno de los resultados esperados de su consulta, la versión dinámica de SQL solo lo cambiará en el alcance de la consulta dinámica, no en el alcance externo, a diferencia de la variación SQLCMD (que, de Por supuesto, tiene un solo alcance).