Category Archives: 15705

Passar um objeto List<string> para uma SP SQL Server, usando XML e LINQ

Surgiu-me a necessidade de passar uma lista de valores variável para uma Stored Procedure de SQL Server. A opção que me pareceu mais adequada foi tirar partido do suporte a XML presente no SQL Server desde a versão 2000.


Primeiro que tudo é necessário passar o objeto List genérico para XML (C#):


List<string> l = new List<string>() { “a”, “b”, “c”, “d”, “e” };
XDocument xmlDocument =
new XDocument(
         
new XDeclaration(“1.0”, “UTF-8″, “yes”),
         
new XElement(
                
“Locations”,
                 l.Select(n =>
new XElement(
                         
“Location”
                          
new XAttribute(“id”, n)))));
string s = xmlDocument.ToString(SaveOptions.DisableFormatting);


 Dado que o XML produzido não se destina a ser humanamente lido, a flag “DisableFormatting” previne que seja adicionadas desnecessárias quebras de linha e indentação. Neste caso escolhi gerar um XL com atributos:


 

Do lado do SQL Server, podemos facilmente gerar uma tabela a partir do XML recebido, que poderemos utilizar como necessário (T-SQL):

DECLARE @x AS XML
SET @x='<?xml version=”1.0″ encoding=”utf-8″?><Locations><Location id=”a”/><Location id=”b”/><Location id=”c”/><Location id=”d”/><Location id=”e”/></Locations>’

DECLARE @i int
EXEC sp_xml_preparedocument @i OUTPUT, @x;

SELECT location
FROM OPENXML(@i, ‘/Locations/Location’, 1)
WITH (location nvarchar(50) ‘@id’ )

EXEC sp_xml_removedocument @i

[2013-12-15] Removi a formatação no código T-SQL e corrigi o código apresentado


<?xml version=”1.0″ encoding=”utf-8″?><Locations><Location id=”a”/><Location id=”b”/><Location id=”c”/><Location id=”d”/><Location id=”e”/></Locations>

Como descobrir em que base de dados se encontra um objecto do qual sabemos o nome? (SQL Server)

Há tempos criei um objecto a partir de um script T-SQL no SQL Server Management Console, numa janela de ‘New Query’. Na altura não reparei que essa janela não estava a apontar para a base de dados pretendida, e agora, semanas depois, não conseguia descobrir a que base de dados daquela instância teria ido parar.

A resolução foi simples, utilizando uma stored procedure interna não documenta do SQL Server, a sp_MSforeachdb, corri o seguinte comando…

 

Exec sp_MSforeachdb ‘Select * From ?..sysobjects where name = ”nome do meu objecto” ‘

 

…e depois foi só procurar no meio dos resultados! Encontrado um resultado, o output não exibia o nome da base de dados onde se encontrava… uma pequena alteração, et voila!

 

Exec sp_MSforeachdb ‘Select ”?”, * From ?..sysobjects where name = ”nome do meu objecto” ‘

 

Também se pode utilizar o operador LIKE caso se saiba apenas uma parte do nome a procurar, podendo filtrar adicionalmente por campos da sysobjects para por ex. restringir os resultados a um tipo de objectos.