{"id":1804,"date":"2025-04-10T13:22:50","date_gmt":"2025-04-10T16:22:50","guid":{"rendered":"https:\/\/thesqltimes.com\/blog\/?p=1804"},"modified":"2025-04-10T13:22:50","modified_gmt":"2025-04-10T16:22:50","slug":"encontrar-dependencias-de-procedures-ultimo-checkdb-e-muito-mais","status":"publish","type":"post","link":"https:\/\/thesqltimes.com\/blog\/2025\/04\/10\/encontrar-dependencias-de-procedures-ultimo-checkdb-e-muito-mais\/","title":{"rendered":"Encontrar depend\u00eancias de procedures, \u00faltimo checkdb e muito mais!"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"Muito \u00fatil!\" data-post-id=\"1804\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Tempo de Leitura:<\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutos<\/span><\/span><p>Se tem um trabalho que sempre me deixou maluco \u00e9 quando temos que analisar uma procedure que referencia outra procedure em outro banco, que referencia uma view, e essa view referencia uma fun\u00e7\u00e3o, que chama outra view que acessa uma tabela no banco original da procedure! AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH! T\u00e1 doido, quem aguenta isso?<\/p>\n<p>Mas, se voc\u00ea quer trabalhar com SQL, principalmente se for consultoria (igual eu), n\u00e3o tem como fugir, mais cedo ou mais tarde voc\u00ea vai pegar um caso desses. Aceite, rs!<\/p>\n<p>A boa not\u00edcia \u00e9 que o sql server tem uma DMV bem legal que armazena todas as refer\u00eancias do c\u00f3digo de views, procedures e functions. E, advinha? Eu j\u00e1 tinha um script onde voc\u00ea passa o nome do objeto e ele usa essa DMV para retornar todas as depend\u00eancias, e as depend\u00eancias das depend\u00eancias e por a\u00ed vai! \u00c9 todo seu (nosso):\u00a0 <a href=\"https:\/\/github.com\/rrg92\/sqlserver-lib\/blob\/main\/Modulos\/DependencyChain.sql\">sqlserver-lib\/Modulos\/DependencyChain.sql at main \u00b7 rrg92\/sqlserver-lib<\/a>.<\/p>\n<p>Aqui um exemplo real do resultado em que precisei usar recente na Power Tuning:<\/p>\n<p id=\"uqcOxaN\"><img loading=\"lazy\" decoding=\"async\" width=\"1337\" height=\"593\" class=\"alignnone size-full wp-image-1805 \" src=\"https:\/\/thesqltimes.com\/blog\/wp-content\/uploads\/2025\/04\/img_67f7e84e9b709.png\" alt=\"\" srcset=\"https:\/\/thesqltimes.com\/blog\/wp-content\/uploads\/2025\/04\/img_67f7e84e9b709.png 1337w, https:\/\/thesqltimes.com\/blog\/wp-content\/uploads\/2025\/04\/img_67f7e84e9b709-300x133.png 300w, https:\/\/thesqltimes.com\/blog\/wp-content\/uploads\/2025\/04\/img_67f7e84e9b709-1024x454.png 1024w, https:\/\/thesqltimes.com\/blog\/wp-content\/uploads\/2025\/04\/img_67f7e84e9b709-768x341.png 768w\" sizes=\"auto, (max-width: 1337px) 100vw, 1337px\" \/><\/p>\n<p>Eu passo ali no filtro o nome do objeto e ele retorna v\u00e1rias informa\u00e7\u00f5es bem legais:<\/p>\n<ul>\n<li>referenced_id \u00e9 o id do objeto dependente e ReferencedObject \u00e9 o nome do objeto. Por exemplo, na primeira linha o nome do objeto referenciando na view que passei come\u00e7a com fncPower, que \u00e9 uma fun\u00e7\u00e3o (descrito pela coluna type_desc, que \u00e9 uma SQL_SCALAR_FUNCTION<\/li>\n<li>RefLevel indica a hierarquia da depend\u00eancia. As duas primeiras linhas tem o valor 1 porque foram encontrados diretamente no c\u00f3digo do objeto que estou procurando. As demais linhas com o valor RefLevel = 2 foram encontradas em algum dos objetos do n\u00edvel 1. Isso nos permite mapear totalmente as depend\u00eancias<\/li>\n<li>E pra fechar, a coluna RefChain mostra uma esp\u00e9cie de caminho, partindo do objeto que voc\u00ea colocou at\u00e9 o objeto da linha respectiva, pra que voc\u00ea bata o olho e entenda a depend\u00eancia. Por exemplo, na pen\u00faltima linha vemos que a view que estou procurando referencia outra view, que por sua vez referencia essa tabela dbo.Power*.<\/li>\n<\/ul>\n<p>O script \u00e9 muito legal n\u00e9?! Mas eu j\u00e1 vi alguns problemas, que devo melhorar no futuro (ou quem sabe algu\u00e9m da comunidade n\u00e3o submete um PR com melhorias):<\/p>\n<ul>\n<li>Temos algumas linhas com NULL no id e tipo porque o objeto referenciado est\u00e1 em outro banco, e n\u00e3o pude obter o resto das informa\u00e7\u00f5es dele<\/li>\n<li>Se umas das depend\u00eancias referencia o objeto que estou procurando, isso provavelmente vai criar um loop infinito na minha query recursiva e vai dar pau. Eu j\u00e1 tenho algumas ideias de como contornar nisso, ent\u00e3o, fica para uma melhoria futura tamb\u00e9m.<\/li>\n<\/ul>\n<p>Al\u00e9m desse script, eu adicionei outros novos que voc\u00ea pode curtir tamb\u00e9m:<\/p>\n<ul>\n<li>Databases\n<ul>\n<li>Listar o <a href=\"https:\/\/github.com\/rrg92\/sqlserver-lib\/blob\/main\/Database\/LastGoodCheckDB.sql\">\u00faltimo checkdb<\/a> de cada banco (cliente Power Tuning que tem o <a href=\"https:\/\/poweralerts.com.br\/\">Power Alerts<\/a> j\u00e1 tem esse script e com alertas e gr\u00e1ficos h\u00e1 muito tempo)<\/li>\n<li>Listar o <a href=\"https:\/\/github.com\/rrg92\/sqlserver-lib\/blob\/main\/Database\/SizePerDatabase.sql\">tamanho alocado e usado<\/a> de todos os bancos<\/li>\n<li>Listar (estimar, na verdade) a<a href=\"https:\/\/github.com\/rrg92\/sqlserver-lib\/blob\/main\/Database\/EstimarUltimoUsoBase.sql\"> \u00faltima vez que um banco de dados foi acessado<\/a> (leitura ou escrita)<\/li>\n<\/ul>\n<\/li>\n<li>Schemas\n<ul>\n<li><a href=\"https:\/\/github.com\/rrg92\/sqlserver-lib\/blob\/main\/Schemas\/ChangeSchemaOwners.sql\">Alterar owners<\/a> de todos os esquemas<\/li>\n<\/ul>\n<\/li>\n<li>Crash Dump\n<ul>\n<li>Listar os <a href=\"https:\/\/github.com\/rrg92\/sqlserver-lib\/blob\/main\/Dumps\/LastDumps.sql\">crash dumps<\/a> e o intervalo, em dias, entre eles (quem tem o <a href=\"https:\/\/poweralerts.com.br\/\">Power Alerts<\/a> tamb\u00e9m j\u00e1 tem alerta do dump h\u00e1 muito tempo)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Fica ligado, que ainda estamos em apenas 100 scripts, e tem mais 400, ainda tem muita coisa pra publicar!<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Se tem um trabalho que sempre me deixou maluco \u00e9 quando temos que analisar uma procedure que referencia outra procedure em outro banco, que referencia uma view, e essa view referencia uma fun\u00e7\u00e3o, que chama outra view que acessa uma tabela no banco original da procedure! AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH! T\u00e1 doido, quem aguenta isso? Mas, se voc\u00ea&hellip;&nbsp;<a href=\"https:\/\/thesqltimes.com\/blog\/2025\/04\/10\/encontrar-dependencias-de-procedures-ultimo-checkdb-e-muito-mais\/\" rel=\"bookmark\"><span class=\"screen-reader-text\">Encontrar depend\u00eancias de procedures, \u00faltimo checkdb e muito mais!<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1805,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[8,3,11,422,7],"tags":[431,33,425,423,428,402,426,429,252,424,73,120,430,427],"series":[],"class_list":["post-1804","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administracao","category-banco-de-dados-2","category-desenvolvimento","category-script-lib","category-sql-server","tag-database-mail","tag-dba","tag-dependencias","tag-expresions","tag-function","tag-github","tag-procedure","tag-scalar-function","tag-script","tag-sp_depends","tag-sql-server","tag-t-sql","tag-udf","tag-view"],"_links":{"self":[{"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/posts\/1804","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/comments?post=1804"}],"version-history":[{"count":5,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/posts\/1804\/revisions"}],"predecessor-version":[{"id":1810,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/posts\/1804\/revisions\/1810"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/media\/1805"}],"wp:attachment":[{"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/media?parent=1804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/categories?post=1804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/tags?post=1804"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/thesqltimes.com\/blog\/wp-json\/wp\/v2\/series?post=1804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}