{"id":93587,"date":"2022-03-21T00:57:50","date_gmt":"2022-03-21T00:57:50","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=93587"},"modified":"2022-03-31T19:47:55","modified_gmt":"2022-03-31T19:47:55","slug":"sql-server-graph-tables-cross-database-surprises","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/sql-server-graph-tables-cross-database-surprises\/","title":{"rendered":"SQL Server Graph Tables &#8211; Cross Database Surprises"},"content":{"rendered":"<p>I was putting together some queries today, pulling data from several databases. One of these is my tables that employ graph tables in SQL Server. As I started part of the query, I used a three part name to access graph table, and used * to fetch the column names in the table (as one does when looking at a few rows from a table):<\/p>\n<p class=\"p1\">SELECT <span class=\"s2\">*<br \/>\n<\/span><span class=\"s3\">FROM<\/span> <span class=\"Apple-converted-space\">\u00a0 <\/span>GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>MarketingContact;<\/p>\n<p>This was greeted with:<\/p>\n<p class=\"p1\">Msg 13924<span class=\"s1\">,<\/span> <span class=\"s2\">Level<\/span> 16<span class=\"s1\">,<\/span> <span class=\"s2\">State<\/span> 1<span class=\"s1\">,<\/span> Line 114<br \/>\n<span class=\"s2\">Select<\/span> <span class=\"s1\">*<\/span> <span class=\"s1\">is<\/span> <span class=\"s1\">not<\/span> permitted because it refers <span class=\"s2\">to<\/span> a <span class=\"s2\">node<\/span> <span class=\"s1\">or<\/span> <span class=\"s2\">edge<\/span> <span class=\"s2\">table<\/span> <span class=\"s3\">&#8216;GraphDBName.IdentityGraph.MarketingContact&#8217;<\/span> which <span class=\"s1\">is<\/span> <span class=\"s1\">not<\/span> <span class=\"s1\">in<\/span> the <span class=\"s2\">current<\/span> <span class=\"s2\">database<\/span><span class=\"s1\">.<\/span><\/p>\n<p>I next tried to let SQL Prompt give me the column names, which were output as:<\/p>\n<p class=\"p1\"><span class=\"s1\">SELECT<\/span> MarketingContact<span class=\"s2\">.<\/span><span class=\"s1\">$node_id<\/span><span class=\"s2\">,<br \/>\n<\/span><span class=\"Apple-converted-space\">\u00a0\u00a0 \u00a0 \u00a0 <\/span>MarketingContact<span class=\"s2\">.<\/span>MarketingContactId<span class=\"s2\">,<br \/>\n<\/span><span class=\"Apple-converted-space\">\u00a0\u00a0 \u00a0 \u00a0 <\/span>MarketingContact<span class=\"s2\">.<\/span>RowCreatedTime<span class=\"s2\">,<br \/>\n<\/span><span class=\"Apple-converted-space\">\u00a0\u00a0 \u00a0 \u00a0 <\/span>MarketingContact<span class=\"s2\">.<\/span>RowLastModifiedTime<br \/>\n<span class=\"s1\">FROM<\/span> <span class=\"Apple-converted-space\">\u00a0 <\/span>GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>MarketingContact;<\/p>\n<p>This returned the following:<\/p>\n<p class=\"p1\">Msg 13923, Level 16, State 5, Line 124<br \/>\nPseudocolumn &#8216;$node_id&#8217; is invalid because it references a node or edge table that is not in the current database.<\/p>\n<p class=\"p1\">Msg 13923, Level 16, State 5, Line 124<br \/>\nPseudocolumn &#8216;$node_id&#8217; is invalid because it references a node or edge table that is not in the current database.<\/p>\n<p class=\"p1\">Msg 13923, Level 16, State 5, Line 124<br \/>\nPseudocolumn &#8216;$node_id&#8217; is invalid because it references a node or edge table that is not in the current database.<\/p>\n<p class=\"p1\">Msg 13923, Level 16, State 5, Line 124<br \/>\nPseudocolumn &#8216;$node_id&#8217; is invalid because it references a node or edge table that is not in the current database.<\/p>\n<p class=\"p1\">Msg 13923, Level 16, State 5, Line 124<br \/>\nPseudocolumn &#8216;$node_id&#8217; is invalid because it references a node or edge table that is not in the current database.<\/p>\n<p>Why so emphatic that this is not the way that it required 5 error messages? Not sure. But either way, no go. It isn&#8217;t that it won&#8217;t work at all across databases. This code works fine:<\/p>\n<p><span class=\"s1\">SELECT<\/span> <span class=\"s1\">TOP<\/span> 10 MarketingContactId<span class=\"s2\">,<\/span><span class=\"Apple-converted-space\">\u00a0 <\/span>ContactId<br \/>\n<span class=\"s1\">FROM<\/span> <span class=\"Apple-converted-space\">\u00a0 <\/span>GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>MarketingContact<span class=\"s2\">,<br \/>\n<\/span><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span>GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>MarketingLink<span class=\"s2\">,<br \/>\n<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>Contact<br \/>\n<span class=\"s1\">WHERE<\/span> <span class=\"s1\">MATCH<\/span><span class=\"s2\">(<\/span>MarketingContact<span class=\"s2\">-(<\/span>MarketingLink<span class=\"s2\">)-&gt;<\/span>Contact<span class=\"s2\">);<\/span><\/p>\n<p>Just understand that if you need any of the graphDb underlying data structures, you will need to find their actual physical name and use it. I would definitely suggest never accessing these columns via any method other than the pseudocolmns for production code (because you have no way to predict the column names from dev to prod (you cannot specify the names when creating a table), but this following code does work:<\/p>\n<p class=\"p1\"><span class=\"s1\">SELECT<\/span> <span class=\"s1\">TOP<\/span> 10 MarketingContactId<span class=\"s2\">,<\/span><span class=\"Apple-converted-space\">\u00a0 <\/span>ContactId,\u00a0<br \/>\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0[$from_id_BC51BB1CD6BE4631A9101A1510560591]<span class=\"s1\">,<\/span> [$to_id_E50693D30F7E41A2B8B29BA31D020332]<br \/>\n<span class=\"s1\">FROM<\/span> <span class=\"Apple-converted-space\">\u00a0 <\/span>GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>MarketingContact<span class=\"s2\">,<br \/>\n<\/span><span class=\"Apple-converted-space\">\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0<\/span>GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>MarketingLink<span class=\"s2\">,<br \/>\n<\/span>\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0GraphDBName<span class=\"s2\">.<\/span>IdentityGraph<span class=\"s2\">.<\/span>Contact<br \/>\n<span class=\"s1\">WHERE<\/span> <span class=\"s1\">MATCH<\/span><span class=\"s2\">(<\/span>MarketingContact<span class=\"s2\">-(<\/span>MarketingLink<span class=\"s2\">)-&gt;<\/span>Contact<span class=\"s2\">);<\/span><\/p>\n<p>Not completely surprising, but might be a bit jarring the first time you see this (and something to know if you are using the underlying graph structures in a way that isn&#8217;t exactly desirable based on how the structures were intended to be used by their creators.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Louis Davidson explains how to get around an interesting issue when doing cross-database queries involving graph database tables.&hellip;<\/p>\n","protected":false},"author":56085,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[136366,4151,4183],"coauthors":[19684],"class_list":["post-93587","post","type-post","status-publish","format-standard","hentry","category-blogs","tag-sql-graph","tag-sql-server","tag-t-sql"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/93587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/56085"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=93587"}],"version-history":[{"count":3,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/93587\/revisions"}],"predecessor-version":[{"id":93705,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/93587\/revisions\/93705"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=93587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=93587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=93587"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=93587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}