-
Notifications
You must be signed in to change notification settings - Fork 993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use @OutputServerName to write results to a linked server #293
Comments
The best way to do this IMO would be to just rewrite the existing @OutputTableName section with some new logic. That way we can avoid unnecessary code bloat. Sounds like fun! I'd like to give it a shot. |
Just an update on this guy. I started working on this feature for sp_Blitz. I know you didn't want fancy error checking, but since I needed to check whether or not there was a linked server on the other side, I added a bit more than just the linked server check. I check if the linked server is valid, then check if the database exists on the linked server. I took the logic for the local location dump out as well, and just put it all in an error checking block that spits out whether or not it's a valid location in bit form.
The first block is error checking for the linked server and it's database. The second block has the check for the local database (no schema check here, though). I basically transplated the local logic from the start of the original block and added error checking for the database name. Otherwise, it just sets the @ValidLocationOutput variable to 0, and the procedure continues as normal. If @ValidOutputLocation is 1, then the Output block begins to run. On the DDL for @OutputTableName, I was hoping to reuse as much code as possible, and simply run the DDL on either server. I came up with a simple solution:
If there's a @ValidOutputServer it will try to execute @StringToExecute AT the @OutputServerName. Since this has to be dynamic, I had to use a nested EXEC...which meant that the string needed a few extra apostrophes around the Schema/Table names during the IF EXISTS checks at the start of the DDL block. Hence the REPLACE functions in the beginning to alter the @StringToExecute. If @ValidOutputServer <> 1, then it will just execute the string as is. Voila! Code reuse! The actual data dump can't reuse code since #BlitzResults only exists on the server. You have to add the linked server components to that query and put it inside of the @ValidOutputServer block.
This should work great! ...or so I thought. The DDL creates the table on the linked/local server just fine, and the logic catches the errors it's supposed to, but the problem is you can't dump any data to it because the table contains an XML column! If you haven't met this 15 year old bug, like I hadn't, let me introduce you: https://connect.microsoft.com/SQLServer/feedback/details/247204/tables-with-xml-columns-cannot-be-queried-using-distributed-llinked-server-queries Since the table that's created has an XML column it can't participate in any Linked Server queries, at ALL, even if your query doesn't touch that column. It doesn't help that the bug has been there since SQL Server 2005. I'm kinda stumped. I can't just cast the #BlitzResults stuff as varchar and use OPENQUERY, I literally can't read/write from any linked server table that has an XML column. Any ideas on how to the best solution for this? Do we just changed the DDL for the linked server table so that QueryPlan is a varchar field? Is it possible to use a global temp table on the linked server to stage the QueryPlan then cast it as XML as we INSERT it into the permanent table? |
My vote would be to just store it as a N/VARCHAR(MAX) and list it as a known issue, unless there's a documented workaround out there. This is a MS 'bug' so I wouldn't spend too much time hair pulling over it. |
It works without any issues going that route. I just added Also, please ignore the horrific messages, these are old servers I've turned into playgrounds... Now to test! I must go down into my dungeon of VMs to find the one with 2008 on it... |
Removed my code from the global temp tables output block. Can only be done locally for now.
Added error checking for people trying to output to a Global Temp Table (##) on a linked server. NO. BAD.
Yeah, I love the NVARCHAR(MAX) route - we had to take this same approach in sp_BlitzFirst - there's a parameter to return XML fields as NVARCHAR because of this exact problem over linked servers. (sigh) |
I haven't tested this, but I'm excited to see it! Thanks for your work, this is so cool to see. |
Some cleanup and renaming things to be more clear. I couldn't get rid of the output from the linked server DB check without dumping the results to a temp table and reading them from there. It's only a single cell with a 1, but I felt kinda dirty doing it. I tried everything though; dynamic linked server queries don't play nice with local variables or OUTPUT.
My pleasure! This has been a great learning experience. There's a lot of nuance to getting dynamic SQL to work with linked server queries that I'd never explored. With regards to testing: I've tested it writing to and from 2008 SP3 (resisted urge to kill it with fire), 2008 R2 SP3, and 2012 SP2. I don't have 2014 to test with, and my 2016 instance is currently Alone and Friendless on AWS©️. If someone wants to try those please do; though I don't see how it would be that different, it's pretty straight forward DDL->INSERT. |
Sure, can you make a pull request for this for the dev branch? |
#293 Support for @OutputServerName in sp_Blitz
Started working on this, brought out output logic into it's own block like I did with sp_Blitz. Not functional yet.
This variable now works on sp_BlitzCache! Same limitations as sp_Blitz when trying to populate an XML field cross server, so query plans return as NVARCHAR(MAX).
This now works in sp_BlitzCache! the principle is the same as before, but the query modification was a bit more complex:
Apart from adding some extra quotation marks around the statements for the more info columns, in order to add the quotation marks around the plan handles and query hashes I had to use QUOTENAME. It's the same in principle though. Question: Do we want to dump the summary table somewhere as well? Right now I'm only outputting plan cache analysis. |
Closing this since it's been a while. |
Are there any plans to finally implement this in sp_BlitzFirst? |
Me? No, that’s why it’s closed. You’re welcome to give it a shot though.
… On Apr 10, 2018, at 5:40 PM, Dan Polivy ***@***.***> wrote:
Are there any plans to finally implement this in sp_BlitzFirst?
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub, or mute the thread.
|
If this parameter is populated, check to see if a linked server exists by this name. If not, print an error.
If the linked server exists, use @OutputDatabaseName, @OutputSchemaName, and @OutputTableName to write the results.
We don't have to do big time error checking here - no need to get fancy and check for the database and the schema for now, can always add that in a later version.
Use case: someone runs the stored procedures regularly as an Agent job, and writes the results to a central server for reporting purposes.
The text was updated successfully, but these errors were encountered: