{"id":9167,"date":"2018-07-12T09:37:24","date_gmt":"2018-07-12T12:37:24","guid":{"rendered":"http:\/\/www.fabriciolima.net\/?p=9167"},"modified":"2018-07-17T10:07:40","modified_gmt":"2018-07-17T13:07:40","slug":"azure-sql-database-como-fazer-um-join-entre-tabelas-de-bases-diferentes","status":"publish","type":"post","link":"https:\/\/fabriciolima.net\/blog\/2018\/07\/12\/azure-sql-database-como-fazer-um-join-entre-tabelas-de-bases-diferentes\/","title":{"rendered":"Azure SQL Database &#8211; Como fazer um join entre tabelas de bases diferentes?"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-9207 aligncenter\" src=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02.png\" alt=\"\" width=\"325\" height=\"231\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02.png 642w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02-300x214.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02-410x292.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02-100x71.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02-275x196.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/AzureSQLDatabaseFotoE02-20x14.png 20w\" sizes=\"auto, (max-width: 325px) 100vw, 325px\" \/><\/p>\n<p>Fala Pessoal,<\/p>\n<p>Continuando a s\u00e9rie de posts sobre o Azure SQL Database, no meu dia a dia de Consultorias \u00e9 bem comum ver sistemas que utilizam mais de uma base de dados para realizar opera\u00e7\u00f5es.<\/p>\n<p>E no Azure SQL Database? Isso funciona?<\/p>\n<p>Vamos testar juntos?<\/p>\n<p>Criei duas bases (<strong>database01<\/strong> e <strong>database02<\/strong>) no meu portal do azure conforme pode ser visto abaixo:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"279\" height=\"143\" class=\"size-full wp-image-9173 aligncenter\" src=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin01.png\" alt=\"\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin01.png 279w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin01-100x51.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin01-275x141.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin01-20x10.png 20w\" sizes=\"auto, (max-width: 279px) 100vw, 279px\" \/><\/p>\n<p>Em seguida criei uma tabela em cada uma dessas bases de dados e populei com algumas informa\u00e7\u00f5es:<\/p>\n<p><strong>Database01:<\/strong><\/p>\n<pre class=\"lang:tsql decode:true\">CREATE TABLE sqlfamily(\r\n ID int IDENTITY(1, 1) NOT NULL PRIMARY KEY,\r\n Nome VARCHAR(50),\r\n Mais_Conhecido_Como VARCHAR(100)\r\n)\r\n \r\nINSERT INTO sqlfamily(Nome, Mais_Conhecido_Como) \r\nVALUES \r\n ( 'Fabricio Lima' ,'Fabricio Lima'),\r\n ( 'Fabiano Amorim' ,'Expert em v\u00eddeos fakes de futebol'),\r\n ( 'Luiz Gareth','Morango do Nordeste' ),\r\n ( 'Arthur Luz', 'Vagalume' ),\r\n ( 'Edvaldo Castro', 'Oldvaldo Castro' )\r\n<\/pre>\n<p><strong>Database02:<\/strong><\/p>\n<pre class=\"lang:tsql decode:true\">CREATE TABLE sqlfamily(\r\n ID int IDENTITY(1, 1) NOT NULL PRIMARY KEY,\r\n Nome VARCHAR(50),\r\n Hobby VARCHAR(100))\r\n \r\nINSERT INTO sqlfamily(Nome, Hobby) \r\nVALUES \r\n( 'Fabricio Lima' ,'Futebol, Corrida, Seriados, Viajar, Rock com a galera, ...'),\r\n( 'Fabiano Amorim' ,'Desafinar uma guitarra...'),\r\n( 'Luiz Gareth','Tomar aquela batida de morango...' ),\r\n( 'Edvaldo Castro', 'Jogar domin\u00f3 na pra\u00e7a...' ),\r\n( 'Arthur Luz', 'Ilimunar Ambientes...' )<\/pre>\n<p>Ap\u00f3s criar e popular as duas tabelas com mesmo nome, mas em bases diferentes, vamos tentar fazer um join nelas para ver o que acontece:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-9172 aligncenter\" src=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02.png\" alt=\"\" width=\"977\" height=\"228\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02.png 1238w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-300x70.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-1024x239.png 1024w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-768x179.png 768w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-700x163.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-410x96.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-100x23.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-275x64.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin02-20x5.png 20w\" sizes=\"auto, (max-width: 977px) 100vw, 977px\" \/><\/p>\n<p><strong>Vixe&#8230; Deu ruim&#8230; E agora Fabr\u00edcio???<\/strong><\/p>\n<p>Pois \u00e9&#8230; No Azure SQL Database n\u00e3o temos suporte para realizar um CROSS database igual realizamos em nossas inst\u00e2ncias On-Premise. S\u00f3 no <a href=\"http:\/\/www.fabriciolima.net\/blog\/2018\/03\/17\/azure-sql-db-managed-instance-introducao\/\" target=\"_blank\" rel=\"noopener\">Azure SQL Managed Instance<\/a> que isso ser\u00e1 poss\u00edvel.<\/p>\n<p><strong>Mas&#8230; Contudo&#8230;Entretanto&#8230;Todavia&#8230;<\/strong><\/p>\n<p>Conseguimos chegar perto disso com a utiliza\u00e7\u00e3o de <strong>EXTERNAL TABLES<\/strong>.<\/p>\n<p>Para fazer isso, vamos executar <strong>TODOS<\/strong> os comandos abaixo na <strong>database01<\/strong>.<\/p>\n<p>Primeiro temos que criar uma <strong>master key:<\/strong><\/p>\n<pre class=\"lang:tsql decode:true\">CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'senhadificil-&gt;123456'<\/pre>\n<p>Quando criei a <strong>database02<\/strong>, eu tamb\u00e9m criei um login chamado <strong>dba_admin<\/strong> para acessar essa base.<\/p>\n<p>Dito isso, vamos criar uma credencial para acessar a <strong>database02<\/strong> com esse login:<\/p>\n<pre class=\"lang:tsql decode:true\">CREATE DATABASE SCOPED CREDENTIAL Db02Credential WITH IDENTITY = 'dba_admin', SECRET = 'senha_user_dba_admin'\r\n<\/pre>\n<p>O pr\u00f3ximo passo \u00e9 criar um <strong>DATA SOURCE<\/strong> que vamos utilizar para acessar o servidor l\u00f3gico e a <strong>database02<\/strong>. Utilizamos a credencial do passo anterior:<\/p>\n<pre class=\"lang:tsql decode:true \">CREATE EXTERNAL DATA SOURCE Db02DataSource WITH\r\n(TYPE = RDBMS, --Query\r\nLOCATION = 'srvfabriciolimasolucoes.database.windows.net', --Servidor logico no azure onde est\u00e1 a base database02\r\nDATABASE_NAME = 'database02',\t--base que queremos acessar com a credencial Db02Credential\r\nCREDENTIAL = Db02Credential\t\t--Db02Credential - credencial que criamos para acessar a base database02\r\n) ;<\/pre>\n<p>Finalmente vamos criar nossa <strong>EXTERNAL TABLE:<\/strong><\/p>\n<pre class=\"lang:tsql decode:true\">CREATE EXTERNAL TABLE dbo.sqlfamily_ext(\r\n\t--ID int,  --Conseguimos retornar menos colunas em uma external table. Ela fica parecida com uma view. N\u00e3o vou usar a coluna ID.\r\n\tNome VARCHAR(50), --se criar a coluna na external table com um tipo de dados diferente, da erro.\r\n\tHobby VARCHAR(100)\r\n)\r\nWITH\r\n(\r\nDATA_SOURCE = Db02DataSource,\r\n  SCHEMA_NAME = 'dbo', --Schema da tabela na database02\r\n  OBJECT_NAME = 'sqlfamily' --Nome da tabela que eu quero referenciar na database02\r\n);<\/pre>\n<p>Essa <strong>EXTERNAL TABLE<\/strong> \u00e9 como se fosse um objeto da base database01, tanto que n\u00e3o conseguimos criar ela com o mesmo nome <strong>sqlfamily<\/strong>. Tive que colocar um sufixo &#8220;_ext&#8221; no nome para diferenciar o nome dos objetos.<\/p>\n<p>Podemos conferir os objetos que criamos nas <strong>DMV&#8217;s<\/strong> abaixo:<\/p>\n<pre class=\"lang:tsql decode:true\">SELECT * FROM sys.symmetric_keys\r\nselect * from sys.external_data_sources; \r\nselect * from sys.database_scoped_credentials\r\nselect * from sys.external_tables; \r\n<\/pre>\n<p>Criada nossa <strong>External Table<\/strong>, agora conseguimos usar ela para acessar a tabela <strong>sqlfamily<\/strong> da database02.<\/p>\n<p>Nosso JOIN fica da seguinte forma:<\/p>\n<pre class=\"lang:tsql decode:true\">SELECT A.nome,\r\n\t   A.Mais_Conhecido_Como,\r\n\t   B.Hobby \r\nFROM database01.dbo.sqlfamily A\r\n\tJOIN database01.dbo.sqlfamily_ext B ON A.Nome = B.nome\r\n<\/pre>\n<p>Agora conseguimos acessar a <strong>database02<\/strong> e pegar a informa\u00e7\u00e3o da coluna <strong>Hobby<\/strong>:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"643\" height=\"149\" class=\"size-full wp-image-9171 aligncenter\" src=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03.png\" alt=\"\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03.png 643w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03-300x70.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03-410x95.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03-100x23.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03-275x64.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin03-20x5.png 20w\" sizes=\"auto, (max-width: 643px) 100vw, 643px\" \/><\/p>\n<p>Essa <strong>EXTERNAL TABLE<\/strong> \u00e9 est\u00e1tica Fabr\u00edcio? Se eu fizer novos inserts na <strong>database02<\/strong> eles v\u00e3o ser retornados automaticamente?<\/p>\n<p>A external table \u00e9 como se fosse um <strong>Linked Server<\/strong> para a <strong>database02<\/strong>. Ou seja, novos inserts ser\u00e3o retornados normalmente por esse join.<\/p>\n<p>Vamos inserir uma linha em cada base para conferir.<\/p>\n<pre class=\"lang:tsql decode:true\">--Rodar na database01\r\nINSERT INTO sqlfamily(Nome, Mais_Conhecido_Como) \r\nVALUES  ( 'Diego Nogare' ,'NogareDBA')\r\n\r\n--Rodar na database02\r\nINSERT INTO sqlfamily(Nome, Hobby) \r\nVALUES  ( 'Diego Nogare' ,'Fazer shrink em arquivos MDF...')<\/pre>\n<p>Executando o <strong>JOIN<\/strong> novamente, nossas linhas que foram inseridas nas duas databases j\u00e1 s\u00e3o retornadas:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" wp-image-9170 aligncenter\" src=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04.png\" alt=\"\" width=\"657\" height=\"318\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04.png 881w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-300x145.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-768x372.png 768w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-700x339.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-410x199.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-100x48.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-275x133.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin04-20x10.png 20w\" sizes=\"auto, (max-width: 657px) 100vw, 657px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Legal Fabr\u00edcio. Eu consigo fazer um insert nessa EXTERNAL TABLE?<\/strong><\/p>\n<p>Resposta:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-9169 aligncenter\" src=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05.png\" alt=\"\" width=\"716\" height=\"220\" srcset=\"https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05.png 716w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05-300x92.png 300w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05-700x215.png 700w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05-410x126.png 410w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05-100x31.png 100w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05-275x84.png 275w, https:\/\/fabriciolima.net\/blog\/wp-content\/uploads\/2018\/07\/postazurejoin05-20x6.png 20w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>N\u00e3o conseguimos fazer um insert. Ela \u00e9 utilizada <strong>apenas para consultas<\/strong>.<\/p>\n<p><strong>E a performance disso Fabr\u00edcio? \u00c9 boa?<\/strong><\/p>\n<p>Excelente pergunta.<\/p>\n<p>Voc\u00ea j\u00e1 deve imaginar a resposta, mas vamos deixar os detalhes para um pr\u00f3ximo post. Aguardem!<\/p>\n<p>Posts Relacionados:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.fabriciolima.net\/blog\/2018\/07\/10\/azure-sql-database-funcao-getdate-com-valor-errado-no-azure-e-isso-mesmo\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.fabriciolima.net\/blog\/2018\/07\/10\/azure-sql-database-funcao-getdate-com-valor-errado-no-azure-e-isso-mesmo\/<\/a><\/li>\n<li><a href=\"http:\/\/www.fabriciolima.net\/blog\/2018\/03\/17\/azure-sql-db-managed-instance-introducao\/\" target=\"_blank\" rel=\"noopener\">www.fabriciolima.net\/blog\/2018\/03\/17\/azure-sql-db-managed-instance-introducao\/<\/a><\/li>\n<\/ul>\n<p><b>Gostou da dica?<\/b><\/p>\n<p>Curta, comente, compartilhe com os coleguinhas\u2026<\/p>\n<p>Assine meu canal no\u00a0<a class=\"external-link wpel-icon-left\" href=\"https:\/\/www.youtube.com\/channel\/UCeBRAO_LLrUdSrOXIywjzRA\" target=\"_blank\" rel=\"external noopener noreferrer nofollow\" data-wpel-link=\"external\">Youtube<\/a>\u00a0e curta minha\u00a0<a class=\"external-link wpel-icon-left\" href=\"https:\/\/www.facebook.com\/FabricioLimaSolucoesemBancodeDados\/\" target=\"_blank\" rel=\"external noopener noreferrer nofollow\" data-wpel-link=\"external\">P\u00e1gina no Facebook<\/a>\u00a0para receber Dicas de Leituras e Eventos sobre SQL Server.<\/p>\n<p>Abra\u00e7os,<\/p>\n<p>Fabr\u00edcio Lima<\/p>\n<p>Microsoft Data Platform MVP<\/p>\n<p>Consultor e Instrutor SQL Server<\/p>\n<p>Trabalha com SQL Server desde 2006<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fala Pessoal, Continuando a s\u00e9rie de posts sobre o Azure SQL Database, no meu dia a dia de Consultorias \u00e9 bem comum ver sistemas que utilizam mais de uma base de dados para realizar opera\u00e7\u00f5es. E no Azure SQL Database? Isso funciona? Vamos testar juntos? Criei duas bases (database01 e database02) no meu portal do [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[1616,1617,1512,280],"tags":[],"class_list":["post-9167","post","type-post","status-publish","format-standard","hentry","category-azure-sql-database","category-managed-instance","category-sql-azure","category-virtual-pass-br"],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/9167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/comments?post=9167"}],"version-history":[{"count":11,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/9167\/revisions"}],"predecessor-version":[{"id":9222,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/posts\/9167\/revisions\/9222"}],"wp:attachment":[{"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/media?parent=9167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/categories?post=9167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fabriciolima.net\/blog\/wp-json\/wp\/v2\/tags?post=9167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}