{"id":882,"date":"2024-05-01T01:31:54","date_gmt":"2024-05-01T01:31:54","guid":{"rendered":"https:\/\/www.fabiodomingos.com\/?p=882"},"modified":"2024-05-01T01:31:54","modified_gmt":"2024-05-01T01:31:54","slug":"sql-server-colocar-resultados-na-mesma-linha-funcoes-for-xml-path-e-stuff","status":"publish","type":"post","link":"https:\/\/www.fabiodomingos.com\/?p=882","title":{"rendered":"SQL Server: Colocar Resultados na mesma linha (Fun\u00e7\u00f5es FOR XML PATH e STUFF)"},"content":{"rendered":"\n<p>Por vezes, existe necessidade de colocarmos os resultados de um query todos na mesma linha, como ocorre quando elaboramos um query para, por exemplo, obter todos os intervenientes de um contrato.<\/p>\n\n\n\n<p>Consideremos ent\u00e3o o seguinte query na base de dados AdventureWorks2019:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>select FirstName, MiddleName, LastName<br>FROM AdventureWorks2019.Person.Person<br>WHERE BusinessEntityID &lt; = 3<\/code><\/pre>\n\n\n\n<p>O resultado ser\u00e1 o seguinte:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.fabiodomingos.com\/wp-content\/uploads\/2024\/04\/1.png\"><img loading=\"lazy\" decoding=\"async\" width=\"242\" height=\"103\" src=\"https:\/\/www.fabiodomingos.com\/wp-content\/uploads\/2024\/04\/1.png\" alt=\"\" class=\"wp-image-883\"\/><\/a><\/figure>\n\n\n\n<p>Uma forma relativamente simples de fazermos esta transforma\u00e7\u00e3o, \u00e9 recorrendo \u00e0s fun\u00e7\u00f5es STUFF e FOR XML PATH.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A fun\u00e7\u00e3o FOR XML PATH<\/h2>\n\n\n\n<p>A fun\u00e7\u00e3o FOR XML PATH, \u00e9 bastante \u00fatil e permite transformar o resultado do nosso query no formato XML, sendo poss\u00edvel passar qual a tag que ser\u00e1 usada para identificar cada registo.<\/p>\n\n\n\n<p>Assim, caso queiramos ter cada registo separado por uma Tag &#8220;Cliente&#8221;, podemos fazer assim:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>select FirstName, MiddleName, LastName<br>FROM AdventureWorks2019.Person.Person<br>WHERE BusinessEntityID &lt; = 3<br>FOR XML PATH('Cliente')<\/code><\/pre>\n\n\n\n<p>O resultado \u00e9 o seguinte:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/www.fabiodomingos.com\/wp-content\/uploads\/2024\/04\/image.png\"><img loading=\"lazy\" decoding=\"async\" width=\"238\" height=\"224\" src=\"https:\/\/www.fabiodomingos.com\/wp-content\/uploads\/2024\/04\/image.png\" alt=\"\" class=\"wp-image-884\"\/><\/a><\/figure>\n\n\n\n<p>No entanto sendo o nosso objetivo apenas separar os nomes por uma v\u00edrgula, devemos ent\u00e3o passar este argumento com &#8221;, por forma a que n\u00e3o colocada qualquer tag entre os nossos resultados e concatenar uma virgula para separar os diversos nomes.<\/p>\n\n\n\n<p>Assim, criando algo deste g\u00e9nero:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>select ', ' + ISNULL(FirstName, '') + ISNULL(MiddleName, '') + ISNULL(LastName, '')\nFROM AdventureWorks2019.Person.Person\nWHERE BusinessEntityID &lt; = 3\nFOR XML PATH('')<\/code><\/pre>\n\n\n\n<p>Temos quase o resultado pretendido:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>, Ken J S\u00e1nchez, Terri Lee Duffy, Roberto Tamburello<\/code><\/pre>\n\n\n\n<p>Como concaten\u00e1mos um elemento e n\u00e3o especific\u00e1mos nenhum nome para a coluna, repare-se que as tags que indicavam os nomes foram tamb\u00e9m removidas, o que permitiu aproximarmo-nos do nosso objetivo, agora falta retirar a virgula inicial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Fun\u00e7\u00e3o STUFF<\/h2>\n\n\n\n<p>De uma forma literal, esta fun\u00e7\u00e3o permite inserir uma string dentro de outra, a sua sintaxe \u00e9 a seguinte:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>STUFF(string inicial, posicaoinicial, numero caracteres a eliminar, expressao a inserir)<\/code><\/pre>\n\n\n\n<p>Para melhor entender, imagine que tendo a seguinte express\u00e3o:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FabioDomingos.com<\/code><\/pre>\n\n\n\n<p>Pretende inserir Marques entre o Fabio e o Domingos, temos ent\u00e3o:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>string inicial: FabioDomingos.com<\/p>\n\n\n\n<p>posicaoinicial: 6<\/p>\n\n\n\n<p>Caracteres a eliminar: 0<\/p>\n\n\n\n<p>Express\u00e3o a Inserir: Marques<\/p>\n<\/blockquote>\n\n\n\n<p>Assim o query dever\u00e1 ser constru\u00eddo da seguinte forma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT STUFF('FabioDomingos.com',6,0,'Marques')<\/code><\/pre>\n\n\n\n<p>O resultado ser\u00e1 ent\u00e3o o pretendido:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FabioMarquesDomingos.com<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Combinando tudo<\/h2>\n\n\n\n<p>O nosso query final, ser\u00e1 algo do seguinte g\u00e9nero:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>SELECT STUFF((SELECT ', ' + REPLACE(ISNULL(FirstName, '') + ' ' + ISNULL(MiddleName, '') + ' ' + ISNULL(LastName, ''), ' ', '')\nFROM AdventureWorks2019.Person.Person\nWHERE BusinessEntityID &lt; = 3\nFOR XML PATH('')), 1, 2, '')<\/code><\/pre>\n\n\n\n<p>Basicamente, indicando 2 no n\u00famero de caracteres a eliminar eliminamos a virgula e o primeiro espa\u00e7o a seguir a esta.<\/p>\n\n\n\n<p>O resultado ent\u00e3o ser\u00e1 o que pretendemos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Ken J S\u00e1nchez, Terri Lee Duffy, RobertoTamburello<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Por vezes, existe necessidade de colocarmos os resultados de um query todos na mesma linha, como ocorre quando elaboramos um query para, por exemplo, obter todos os intervenientes de um contrato. Consideremos ent\u00e3o o seguinte query na base de dados AdventureWorks2019: O resultado ser\u00e1 o seguinte: Uma forma relativamente simples de fazermos esta transforma\u00e7\u00e3o, \u00e9 &#8230; <a title=\"SQL Server: Colocar Resultados na mesma linha (Fun\u00e7\u00f5es FOR XML PATH e STUFF)\" class=\"read-more\" href=\"https:\/\/www.fabiodomingos.com\/?p=882\" aria-label=\"Leia mais sobre SQL Server: Colocar Resultados na mesma linha (Fun\u00e7\u00f5es FOR XML PATH e STUFF)\">Ler mais<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":340,"footnotes":""},"categories":[3,61,62],"tags":[68],"class_list":["post-882","post","type-post","status-publish","format-standard","hentry","category-microsoft","category-sql-server","category-t-sql","tag-sql"],"_links":{"self":[{"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=\/wp\/v2\/posts\/882","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=882"}],"version-history":[{"count":1,"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=\/wp\/v2\/posts\/882\/revisions"}],"predecessor-version":[{"id":886,"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=\/wp\/v2\/posts\/882\/revisions\/886"}],"wp:attachment":[{"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=882"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=882"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fabiodomingos.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=882"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}