Preciso refatorar e documentar uma série de foo.sql
consultas que serão compartilhadas por uma equipe de suporte técnico da DB (para configurações do cliente e coisas assim). Existem tipos de tickets que vêm regularmente onde cada cliente tem seus próprios servidores e bancos de dados, mas, caso contrário, o esquema é o mesmo em todos os aspectos.
Os procedimentos armazenados não são uma opção no momento atual. Estou discutindo se usará SQLCMD dinâmico ou, também não usei muito, pois sou um pouco novo no SQL Server.
Script SQLCMD Sinto-me definitivamente "mais limpo" para mim e mais fácil de ler e fazer pequenas alterações nas consultas, conforme necessário, mas também força o usuário a ativar o modo SQLCMD. A dinâmica é mais difícil, pois o destaque da sintaxe é a perda devido à consulta da escrita usando manipulação de string.
Eles estão sendo editados e executados usando o Management Studio 2012, versão SQL 2008R2. Quais são alguns dos prós / contras de qualquer método ou algumas das "práticas recomendadas" do SQL Server em um método ou outro? Um deles é "mais seguro" que o outro?
Exemplo 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);
Exemplo 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));
fonte
use ...
seu script? É importante para a execução correta da consulta subsequente? Estou perguntando, porque se a alteração do banco de dados atual é um dos resultados esperados da sua consulta, a versão dinâmica do SQL somente a altera no escopo da consulta dinâmica, não no escopo externo, ao contrário da variação SQLCMD (que, de claro, tem apenas um escopo).use
declaração provavelmente pode ficar de fora, pois o escopo não será alterado durante esse script específico. Eu tenho um pequeno número de casos de uso em que haverá pesquisas entre servidores, mas isso pode estar além do escopo desta postagem.Respostas:
Apenas para tirar isso do caminho:
Tecnicamente falando, essas duas opções são consultas "dinâmicas" / ad hoc que não são analisadas / validadas até serem enviadas. E ambos são suscetíveis a injeção SQL uma vez que eles não estão parametrizados (embora com os scripts SQLCMD, se você estiver passando em uma variável de um script CMD, em seguida, você tem a oportunidade de substituir
'
com''
, que pode ou não funcionar, dependendo de onde o variáveis estão sendo usadas).Existem prós e contras em cada abordagem:
Se o pessoal de suporte não estiver fazendo consultas ad hoc e apenas preenchendo essas variáveis, elas não precisam estar no SSMS, onde podem editar esses scripts e fazer alterações indesejadas.
Eu criaria scripts CMD para solicitar ao usuário os valores variáveis desejados e depois chamar SQLCMD.EXE com esses valores. O script CMD pode até registrar a execução em um arquivo, completo com registro de data e hora e valores variáveis enviados.
Crie um script CMD por script SQL e coloque em uma pasta compartilhada em rede. Um usuário clica duas vezes no script CMD e ele simplesmente funciona.
Aqui está um exemplo que:
%OrderIDsSeparatedByCommas%
como a variável SQLCMD$(OrderIDsSeparatedByCommas)
Teste o script SQL (nomeado: FixProblemX.sql ):
Script CMD (nomeado: FixProblemX.cmd ):
Certifique-se de editar a
ScriptLogPath
variável na parte superior do script.Além disso, os scripts SQL (especificados pela opção da
-i
linha de comandos para SQLCMD.EXE ) podem se beneficiar de ter um caminho completo, mas não totalmente certo.fonte