T-sql and json and XML - sql-server

Does anybody know how to get intellisense working in query windows in SSMS for JSON methods?
I'm just getting started with querying from remote databases and for some reason when I attempt to type in methods, e.g., isjson() in the t-sql editor, not showing any of the functions.
Do I need to import any packages?

You can use Json Format by create this procedure :
CREATE PROCEDURE [dbo].[sp_query_json]
#query nvarchar(4000)
AS
BEGIN
SET NOCOUNT ON;
Declare #query_adjust nvarchar(max)
set #query_adjust = 'select ' + '''['''
+ ' + replace(replace(replace(replace(replace(('
+ #query + ' for xml raw ),'
+ '''<row ''' + ',' + '''{"''' + '),'
+ '''/>''' + ',' + '''},''' + '),'
+ '''" ''' + ',' + '''","''' + '),'
+ '''="''' + ',' + '''":"''' + ') + '
+ ''']''' + ','
+ ''',]''' + ',' + ''']''' + ')'
EXECUTE sp_executesql #query_adjust
END
You can test query like that :
EXECUTE [dbo].[sp_query_json] 'select id,name from table'
this call real Table or View and change it to XML by using
For XML RAW
And replace XML tags to JSON like

Related

Dynamic T-SQL WITH Statement Error

I am building a dynamic T-SQL script and running into some errors.
PRINT 'Convert References into XML fields'
SET #query = N';WITH DCODES AS (' +
'SELECT [id],[Codes],' +
'CAST(''<M>'' + REPLACE([Codes],'','' , ''</M><M>'') + ''</M>'' AS XML) AS [XML_Codes],' +
'CAST(''<M>'' + REPLACE(REPLACE([Descriptions],''&'',''AND''),'','',''</M><M>'') + ''</M>'' AS XML) AS [XML_Desc] ' +
'FROM ##' + #system_name + '_Temp)'
EXEC sp_executesql #query
The code works if I write the statement as a static statement. When I run this in my dynamic script this error.
--Msg 102, Level 15, State 1, Line 1
--Incorrect syntax near ')'.
I tried to rewrite it, but I still get this issue.
missing line below
SET #query = N';WITH DCODES AS (' +
'SELECT [id],[Codes],' +
'CAST(''<M>'' + REPLACE([Codes],'','' , ''</M><M>'') + ''</M>'' AS XML) AS [XML_Codes],' +
'CAST(''<M>'' + REPLACE(REPLACE([Descriptions],''&'',''AND''),'','',''</M><M>'') + ''</M>'' AS XML) AS [XML_Desc] ' +
'FROM ##' + #system_name + '_Temp) select * from DCODES' -- you are missing this

Adding Quoted Datetimes from Paramaters in Dynamic SQL String for sp_executesql

I am currently working on an SQL Server 2005, and trying to structure a dynamic query as follows:
DECLARE #GETDATE AS NVARCHAR(12);
DECLARE #GETDATE2 AS NVARCHAR(12);
SET #GETDATE = ...;
SET #GETDATE2 = ...;
SET #SQL =
'CREATE TABLE [dbo].[' + #TABLENAME + ']'
+'('
+'ShibNo' 'INT'
+')'
+';'
+ CHAR(10)
+'INSERT INTO [dbo].[' + #TABLENAME + '] (ShibNo)'
+'SELECT X.[ShibNo]'
+'FROM'
+'('
+'SELECT'
+ 'I.[Shibno]'
+',' + 'I.[ShibAzmnDate]'
+',' + 'I.[ShibBeginTime]'
+',' + 'I.[ShibEndTime]'
+',' + 'I.[CarNum]'
+',' + 'I.[DriverNo1]'
+',' + 'I.[ShibKind]'
+',' + 'I.[FStationID]'
+',' + 'I.[LStationID]'
+',' + 'I.[LineDetailRecordID]'
+'FROM Inserted2 I'
+'WHERE I.[ShibAzmnDate] BETWEEN ' + #GETDATE + ' AND ' + #GETDATE2 +
+'INTERCEPT'
+'SELECT'
+ 'D.[Shibno]'
+',' + 'D.[ShibAzmnDate]'
+',' + 'D.[ShibBeginTime]'
+',' + 'D.[ShibEndTime]'
+',' + 'D.[CarNum]'
+',' + 'D.[DriverNo1]'
+',' + 'D.[ShibKind]'
+',' + 'D.[FStationID]'
+',' + 'D.[LStationID]'
+',' + 'D.[LineDetailRecordID]'
+'FROM Deleted2 D'
+'WHERE D.[ShibAzmnDate] BETWEEN ' + #GETDATE + ' AND ' + #GETDATE2 +
+') AS X'
+';'
;
EXECUTE sp_executesql #SQL
;
As you can see, there are parameters in the WHERE clauses of the query string which are meant to restrict the date range of the checks performed here. However, when the string is executed as a query using sp_executesql, the dates don't receive the proper apostrophe punctuation, which creates errors.
I have tried using replace and escaping the characters, but apparently do not know the proper way to do this. I would be very happy (and grateful!) to learn how to do this correctly.
The string returned if I check the build-up of the query is one of the following variations:
' WHERE D.[ShibAzmnDate] BETWEEN ''03/13/2016'' AND ''03/14/2016'' '
OR
' WHERE D.[ShibAzmnDate] BETWEEN 03/13/2016 AND 03/14/2016 '
OR
' WHERE D.[ShibAzmnDate] BETWEEN ''''03/13/2016'''' AND ''''03/14/2016'''' '
and so on...
Can someone please help me to understand how to properly structure this dynamic query string (and future dynamic query strings) to avoid this issue?
Many, many thanks in advance!
Use parameter placeholders in the query, and then pass the values of the parameters to sp_executesql. See https://msdn.microsoft.com/en-us/library/ms188001.aspx for more details.
DECLARE #GETDATE AS NVARCHAR(12);
DECLARE #GETDATE2 AS NVARCHAR(12);
SET #GETDATE = ...;
SET #GETDATE2 = ...;
SET #SQL =
'CREATE TABLE [dbo].[' + #TABLENAME + ']'
+'('
+'ShibNo' 'INT'
+')'
+';'
+ CHAR(10)
+'INSERT INTO [dbo].[' + #TABLENAME + '] (ShibNo)'
+'SELECT X.[ShibNo]'
+'FROM'
+'('
+'SELECT'
+ 'I.[Shibno]'
. . .
+'FROM Inserted2 I'
+'WHERE I.[ShibAzmnDate] BETWEEN #StartDate AND #EndDate'
+'INTERCEPT'
+'SELECT'
+ 'D.[Shibno]'
. . .
+'FROM Deleted2 D'
+'WHERE D.[ShibAzmnDate] BETWEEN #StartDate AND #EndDate'
+') AS X'
+';'
;
EXECUTE sp_executesql #SQL, N'#StartDate DATE, #EndDate DATE',
#StartDate = #GETDATE, #EndDate = #GETDATE2
;
Try it is working for me.
DECLARE #DATE VARCHAR(250) = '2016-01-01', #VAR VARCHAR(MAX)
SELECT #VAR = 'SELECT * FROM TABLE_A WHERE CREATE_DTE> '''+#DATE+''''
SELECT #VAR
1 MSSQL supports multiline string literals so you don't have to concat each line separately (don't quite understand why are you concatenating comma as a separate litera)
2 Since you are using sp_executesql and have variables of appropriate type you don't need them in sql text and don't have to convert them to varchar
SET #SQL =
cast('CREATE TABLE [dbo].[' as nvarchar(max)) + #TABLENAME + ']
(
ShibNo INT
);
INSERT INTO [dbo].[' + #TABLENAME + '] (ShibNo)
SELECT X.[ShibNo]
FROM
(
SELECT
I.[Shibno]
,I.[ShibAzmnDate]
,I.[ShibBeginTime]
,I.[ShibEndTime]
,I.[CarNum]
,I.[DriverNo1]
,I.[ShibKind]
,I.[FStationID]
,I.[LStationID]
,I.[LineDetailRecordID]
FROM Inserted2 I
WHERE I.[ShibAzmnDate] BETWEEN #date1 AND #date2
INTERCEPT
SELECT
D.[Shibno]
,D.[ShibAzmnDate]
,D.[ShibBeginTime]
,D.[ShibEndTime]
,D.[CarNum]
,D.[DriverNo1]
,D.[ShibKind]
,D.[FStationID]
,D.[LStationID]
,D.[LineDetailRecordID]
FROM Deleted2 D
WHERE D.[ShibAzmnDate] BETWEEN #date1 AND #date2
) AS X'
EXECUTE sp_executesql #SQL, N'#date1 datetime, #date2 datetime', #getdate, #getdate2;

SQL Server special characters significance in fetch sp

In the following fetch sp of sql server 2008R2, what does-> /^/ these characters symbolise in the column names in the select statement in #object?
CREATE Proc Pr_FetchPatientIssueItemsMis
As
Begin
Declare #Object varchar(MAX)
SET NOCOUNT ON
Set #Object= '(Select '
+ 'ISD.[' + /*v*/'SalesID'/*v*/ + '] SalesID,'
+ 'ISD.[' + /*v*/'ItemID'/*v*/ + '] ItemID,'
+ 'V.DisplayName ItemName,'
+ 'V.ItemCode ItemCode,'
+ 'v.CategoryID CategoryID,'
+ 'v.Category Category'
+ ' From Dbo.[' + /*v*/'V_ItemPatientIssues'/*v*/ + ']ISD'
+ ' Inner Join Dbo.[v_items]V ON ISD.[' + /*v*/'ItemID'/*v*/ + ']= V.ItemID'
+ ')OBJ'
EXEC('Select * from (Select * From ' + #Object +')XYZ')
Return 0
End
They are in-line comments. They don't do anything. The only thing that they could symbolize would be some documentary meaning that was totally up to whoever wrote it.
My off-hand guess would be that whoever wrote this uses this procedure as a template to generate other procedures by doing searches on pairs of the /*v*/ and replacing whatever's between them with different table/column names.

SQL Server : execute dynamic sql help please

EXEC SP_EXECUTESQL
#DynamicSQL
, N'#HostIDs VARCHAR(MAX) OUTPUT'
, #HostIDs OUTPUT;
PRINT #HostIDs;
SELECT #HostIDs AS HostIDs;
SET #UpdateSQL = '
EXECUTE [dbo].[usp_Win7_HostUpdater_NEW]
#HostID = ''' + #HostIDs + ''' ,
#PackageID = ''' + #PackageID + ''' ,
#MigrationFlag = ''' + #MigrationFlagID + ''' ,
#Manufacturer = ' + #Manufacturer + ' ,
#Product = ' + #Product + ' ,
#Version = ' + #Version + ' ,
#Reason = ' + #Reason + ' ,
#Contact = ' + #Contact + '
';
SELECT #UpdateSQL AS UpdateSQL;
PRINT #UpdateSQL;
EXEC( #UpdateSQL )
END
I have a stored procedure on both a SQL Server 2005 and 2008 in which the above code is the last part of
it returns a VARCHAR(MAX) of numbers separated by commas.
Now this returned value is large upwards of 600k characters. If I execute this on a SQL Server 2005 it works like 50% of the time, #HostIDs is populated always and #UpdateSQL gets generated with the correct values and is executed.
On SQL Server 2008, #HostIDs is populated but #UpdateSQL is always NULL
This is weirding me out tremendously
Can anyone maybe shed some light on my odd problem?
Check these out
SET CONCAT_NULL_YIELDS_NULL OFF
select 'abc' + null + 'def'
--- abcdef
SET CONCAT_NULL_YIELDS_NULL ON
select 'abc' + null + 'def'
--- NULL
That's one way to get around the problem, which is to set it off before your string building and back on after. Any NULL in the sequence of string concatenation renders the entire statement NULL, which explains it works like 50% of the time - these are when all of the variables are non-null.
Completely agree with freefaller though, unless the question's an abstraction of a larger puzzle, there's no reason to build a dynamic SQL and EXEC it when a direct execution will work for the particular snippet shown.
If any of the parameters are null, the entire statement will be null. You can work around it by doing something like this (and I don't know what the data types are, but sometimes you need to cast them to varchar from int/bool/etc. types to make the concatenation work):
SET #UpdateSQL = '
EXECUTE [dbo].[usp_Win7_HostUpdater_NEW]
#HostID = ' + ISNULL('''' + #HostIDs + '''', 'null') + ' ,
#PackageID = ' + ISNULL('''' + #PackageID + '''', 'null') + ' ,
#MigrationFlag = ' + ISNULL('''' + #MigrationFlagID + '''', 'null') + ' ,
#Manufacturer = ' + ISNULL(#Manufacturer, 'null') + ' ,
#Product = ' + ISNULL(#Product, 'null') + ' ,
#Version = ' + ISNULL(#Version, 'null') + ' ,
#Reason = ' + ISNULL(#Reason, 'null') + ' ,
#Contact = ' + ISNULL(#Contact, 'null') + '
';
It causes because you are not handling nulls
you can use sp_executesql instead of exec it has some benefits over exec

SQLServer conditional execution within 'EXEC' if a column exists

I'm new to SQLServer scripting (normally being a C++ developer), and would really appreciate a bit of assistance.
I am attempting to perform a "find and replace" update on all tables in a SQLServer database that contain a 'PROJID' column. I am really struggling to find a way to do this that doesn't report to me:
Msg 207, Level 16, State 1, Line 1 Invalid column name 'PROJID'.
The statement I am executing is:
EXEC
(
'IF EXISTS(SELECT * FROM sys.columns WHERE name = N''PROJID'' AND Object_ID = Object_ID(N''' + #TableName + '''))' +
' BEGIN' +
' UPDATE ' + #TableName +
' SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ',''' + #ReplaceIDStr + ''',''' + #FindIDStr + ''')' +
' WHERE ' + #ColumnName + ' LIKE ''' + #ReplaceIDStr + '''' + ' AND PROJID = ''1000''' +
' END'
)
I have also tried using:
'IF COL_LENGTH(''' + #TableName + ''',''PROJID'') IS NOT NULL' +
instead of the column-exist check above. This also still gives me the "Invalid Column Name" messages.
I would be happy to take the column-exist check outside of the 'Exec' statement, but I'm not sure how to go about doing this either.
You just need to do it in a different scope.
IF EXISTS (SELECT 1 FROM sys.columns ...)
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'UPDATE ...';
EXEC sp_executesql #sql;
END
Output the results of this query to text. Don't forget to change the values of the variables! Take the result of this and run it.
SET NOCOUNT ON
DECLARE #ColumnName VARCHAR(200) = 'ReplaceColumn'
, #ReplaceIdStr VARCHAR(200) = 'ExampleReplaceIdStr'
, #FindIdStr VARCHAR(200) = 'ExampleFindIdStr'
PRINT 'BEGIN TRAN'
PRINT 'SET XACT_ABORT ON'
SELECT
'UPDATE ' + C.TABLE_NAME + CHAR(13)
+ 'SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ', ''' + #ReplaceIdStr + ''', ''' + #FindIdStr + ''')' + CHAR(13)
+ 'WHERE ' + #ColumnName + ' LIKE ''%' + #ReplaceIdStr + '%'' AND PROJID = ''1000''' + CHAR(13)
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'PROJID'
PRINT 'COMMIT TRAN'
SET NOCOUNT OFF
EDIT: Also, some reasoning: You said you want update all tables where they contain a column called PROJID. Your first query just says that if the table #TableName has a PROJID column, then update #ColumnName on it. But it doesn't guarantee that it has #ColumnName on it. The query I gave doesn't check that either, because I'm assuming that all tables that have PROJID also have #ColumnName. If that isn't the case, let me know and I can update the answer to check that. That you're getting an Invalid Column Name error points to #ColumnName not existing.
Your query would have updated one table (#TableName) at most, whereas the one I gave you will update every table that has PROJID. I hope that's what your going for.
EDIT 2: Here is a version that would run it all at once:
DECLARE #ColumnName VARCHAR(200) = 'Value'
, #ReplaceIdStr VARCHAR(200) = 'ExampleReplaceIdStr'
, #FindIdStr VARCHAR(200) = 'ExampleFindIdStr'
DECLARE #Sql NVARCHAR(MAX)
DECLARE UpdateCursor CURSOR FOR
SELECT
'UPDATE ' + C.TABLE_NAME
+ ' SET ' + #ColumnName + ' = REPLACE(' + #ColumnName + ', ''' + #ReplaceIdStr + ''', ''' + #FindIdStr + ''')'
+ ' WHERE ' + #ColumnName + ' LIKE ''%' + #ReplaceIdStr + '%'' AND PROJID = ''1000'''
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.COLUMN_NAME = 'PROJID'
OPEN UpdateCursor
FETCH NEXT FROM UpdateCursor
INTO #Sql
WHILE ##FETCH_STATUS = 0
BEGIN
EXEC sp_executesql #Sql
FETCH NEXT FROM UpdateCursor
INTO #Sql
END
CLOSE UpdateCursor
DEALLOCATE UpdateCursor

Resources