I don't have much experience with dynamic procedures so the following was only an attempt.
The only part that is actually dynamic here is the table name which I tried to create by combining the fix part "MOC_" and the variable part #level.
Can someone tell me what I have to change here to make this work ?
The error I get when executing this points to the IF NOT EXISTS part:
Conversion failed when converting the nvarchar value 'IF NOT EXISTS (
SELECT *
FROM MOC_Nav2
WHERE itemID = ' to data type int.
My procedure:
ALTER PROCEDURE [dbo].[MOC_UpdateNav]
#level nvarchar(20),
#itemID int,
#parentID int,
#itemName nvarchar(100),
#sortID int,
#logStatus nvarchar(20),
#lastUpdate nvarchar(50),
#modBy varchar(50)
AS
BEGIN
SET NOCOUNT ON;
BEGIN
DECLARE #sql nvarchar(max)
SET #sql = 'IF NOT EXISTS
(
SELECT *
FROM MOC_' + #level + '
WHERE itemID = ' + #itemID + '
)
INSERT INTO MOC_' + #level + '
(
parentID,
itemName,
sortID,
logStatus,
lastUpdate,
modDate,
modBy
)
SELECT ' + #parentID + ',
' + #itemName + ',
' + #sortID + ',
' + #logStatus + ',
' + #lastUpdate + ',
GETDATE(),
' + #modBy + '
ELSE
UPDATE MOC_' + #level + '
SET parentID = ' + #parentID + ',
itemName = ' + #itemName + ',
sortID = ' + #sortID + ',
logStatus = ' + #logStatus + ',
lastUpdate = ' + #lastUpdate + ',
modDate = GETDATE(),
modBy = ' + #modBy + '
WHERE itemID = ' + #itemID + ''
EXEC(#sql)
END
END
#itemID is an int. Because it is used in the expression, everything else must be converted to a number, including your SQL text.
Convert #itemID (and other numbers) to nvarchar before concatenating it into the query:
SET #sql = N'IF NOT EXISTS
(
SELECT *
FROM MOC_' + #level + '
WHERE itemID = ' + cast(#itemID as nvarchar(30)) + ...
Related
i am having a data conversion issues when applying this un-pivoted script on my dynamic columns SSRS report .every time SSRS Report is executed the header columns are supposedly to change .
IF OBJECT_ID('tempdb..##Temp') IS NOT NULL
DROP TABLE ##Temp;
DECLARE #ObjectName VARCHAR(100) = '[AdventureWorks2016].[Sales].[SalesOrderHeader]' ,
#KeyColumn VARCHAR(100) = '[SalesOrderID]';
DECLARE #ColumnNames NVARCHAR(MAX)= '' ,
#Values NVARCHAR(MAX)= '' ,
#SQL NVARCHAR(MAX)= '';
SELECT #ColumnNames += ',
' + QUOTENAME([ShipDate]) ,
#Values += ',
' + QUOTENAME([ShipDate]) + ' = CONVERT(VARCHAR(100), '
+ QUOTENAME([ShipDate]) + ')'
FROM [AdventureWorks2016].[Sales].[SalesOrderHeader]
WHERE '[Sales].[SalesOrderHeader]' = #ObjectName
AND [ShipDate] <> #KeyColumn;
SET #SQL = N'Select * into ##Temp
FROM
(
SELECT ' + #KeyColumn + #Values + '
FROM ' + #ObjectName + '
) AS DRV
UNPIVOT
(
Value FOR ColumnName IN (' + STUFF(#ColumnNames, 1, 1, '') + ')
) AS UnPVT;';
EXEC sp_executesql #SQL;
SELECT *
FROM ##Temp
I am using the following dynamic query, but see that the performance is slow. I am not a big fan of dynamic SQL, and am looking for, if possible, a good clean and fast SQL alternative for the following. Thanks a million ton in advance! Here are some details:
In the following code, the final table missingfields_xxxx lists out the rows where we have a missing rule field.
table_name has the column rule that holds the column name of the table trans_modelname (this table can be found in the dynamic part of the sql)
DECLARE #rule NVARCHAR(MAX)
DECLARE #PeriodNumber INT = 1
DECLARE #SelectList NVARCHAR(MAX)
DECLARE #WhereList NVARCHAR(MAX)
DECLARE #SQL NVARCHAR(MAX)
DECLARE #ModelName as NVARCHAR(MAX) = 'modelname'
--DECLARE #MaxPeriods INT = 8
DECLARE #MaxPeriods INT
SELECT #MaxPeriods = count (*)
FROM
(
SELECT [rule]
FROM table_name
WHERE ModelName = #ModelName) ab
DECLARE db_cursor3 CURSOR FOR
SELECT * FROM
(
SELECT [rule]
FROM table_name
WHERE ModelName = #ModelName) cd
OPEN db_cursor3
FETCH NEXT FROM db_cursor3 INTO #rule
WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN
SELECT #SelectList = COALESCE(#SelectList + ', ', '') + '' + #rule + ' AS [GLSegment_' + RIGHT('00' + CAST(#PeriodNumber AS VARCHAR), 3) + ']'
SELECT #SelectList as 'Selectlist'
IF #PeriodNumber < #MaxPeriods
BEGIN
SELECT #WhereList = COALESCE(#WhereList, '') + '(isnull([GLSegment_' + RIGHT('00' + CAST(#PeriodNumber AS VARCHAR), 3) + '],'''') = '''' ) OR '
SELECT #WhereList as 'Wherelist where periodnumber < maxperiods'
END
ELSE IF #PeriodNumber = #MaxPeriods
BEGIN
SELECT #WhereList = COALESCE(#WhereList, '') + '(isnull([GLSegment_' + RIGHT('00' + CAST(#PeriodNumber AS VARCHAR), 3) + '], '''') = '''' )'
SELECT #WhereList as 'Wherelist where periodnumber = maxperiods'
END
SET #PeriodNumber = #PeriodNumber + 1
END
FETCH NEXT FROM db_cursor3 INTO #rule
END
CLOSE db_cursor3
DEALLOCATE db_cursor3
-- build dynamic query
SET #SQL =
'SELECT * into missingfields_' + #ModelName + ' from trans_' + #ModelName + '
WHERE id in
(
SELECT id from
(
SELECT id, ' + #SelectList + '
FROM trans_' + #ModelName + ')A
WHERE ' + #WhereList + '
);
SELECT * from missingfields_' + #ModelName
PRINT #SQL
print 'missingfields_' + #ModelName
EXEC sp_executesql #SQL
I have four columns in a table ID, Longitude, Latitude, and SpatialData. I have the first three columns filled out for every row, but I need to enter in the SpatialData for each row. I can currently manually update the SpatialData column by using the below query:
update GioMap set SpatialData = 'Point(-74.009506 40.70602)' Where ID =1
From here I have to keep manually updating the Longitude, Latitude and ID for every row. I am using this code to try to loop through all of the rows and update the table that way:
DECLARE #LoopC INT = 1, #MaxOID INT,
#Long nVarchar(32), #Lat nVarchar(32),#Col1 nVarchar(11)
SET #MaxOID = (select count(*) from GioMap)
Set #Col1 = 'SpatialData'
WHILE(#LoopC <= #MaxOID)
BEGIN
SET #Long = (Select Longitude FROM GioMap where ID = #LoopC)
SET #Lat = (Select Latitude FROM GioMap where ID = #LoopC)
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
EXEC sp_executesql #sql
SET #LoopC = #LoopC + 1
END
When I run this code I keep getting this error message:
Msg 245, Level 16, State 1, Line 13
Conversion failed when converting the nvarchar value 'update [ISSHXI1].[dbo].[GioMap] set SpatialDat = 'Point(-74.0095 40.706)' Where ID = ' to data type int.
I don't understand why it would be trying to convert it to an int?
You could do something like this:
UPDATE GioMap SET SpatialData = 'Point(' + cast(Longitude as varchar) + ' ' + cast(Latitude as varchar) + ')'
I think the way you are doing it is bad, but that's not technically what you asked.
It is trying to convert it to an int because you are adding a varchar to an int. You need to change this:
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' +
'''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' +
#LoopC)
to this
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' +
'''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' +
Cast(#LoopC as varchar))
The point statement paramaters need to be seperated by a comma.
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
Instead of:
#Long + ' ' + #Lat + ')
try
#Long + ',' + #Lat + ')
To see what is being executed you can try adding a print statement:
DECLARE #sql VARCHAR(MAX) = ('update GioMap set ' + #Col1 +' = ' + '''' + 'Point(' + #Long + ' ' + #Lat + ')' + '''' + ' Where ID = ' + #LoopC)
print #sql
EXEC sp_executesql #sql
Also why do you parans around strings you are assigning? Its confusing in TSQL. While it works it is jarring and unusual.
Instead of:
SET #MaxOID = (select count(*) from GioMap)
try
SET #MaxOID = 'select count(*) from GioMap'
Later in the code you do both parens and quotes. The great, great majority of TSQL developers just use single quotes.
Ben
I need to create a mssql query, in that query i would like to put 8 parameters, they are:
table_primary_key : primary key column name,
table_name : table name,
start_row : starting from this row,
limit_row : end row,
column_name : where column name,
column_value : where column name = column value,
sort_by : sort by column name.
order : ASC / DESC.
note: the bold one is the one i haven't implemented yet.
my current query is this :
SELECT *
FROM (
SELECT *,
ROW_NUMBER() OVER (ORDER BY *sort_by*) as row
FROM *table_name*
) a
WHERE row > *start_row* AND row <= *limit_row*
my question is how I add table_primary_key, column_name, column_value, order to my current query?
my goal is make query display data from a table_name, start from
start_row until limit_row, where column_name = column_value. and the
data will be sort by sort_by and the order is according to order
if my question int clear enough please ask, thanks
You can try to use dynamic sql expression like this:
declare
#table_primary_key varchar(max) = 'ProjectID',
#table_name varchar(max) = 'ProjectList',
#start_row int = 10,
#limit_row int = 20,
#column_name varchar(max) = 'ProjectStatus',
#column_value varchar(max) = '5',
#sort_by varchar(max) = 'ProjectName',
#order varchar(4) = 'ASC' -- 'DESC'
declare
#sql varchar(max) = ''
set #sql = 'SELECT * FROM ( '
+ 'SELECT ' + #table_primary_key + ', ROW_NUMBER() OVER (ORDER BY ' + #sort_by + ' ' + #order + ') as row FROM ' + #table_name + ' WHERE ' + #column_name + ' = ''' + #column_value + ''') a'
+ ' WHERE row > ' + cast(#start_row as varchar) + ' and row <= ' + cast(#limit_row as varchar)
exec ( #sql )
Or you can use stored procedure
create procedure dbo.GetResults
(
#table_primary_key varchar(max),
#table_name varchar(max),
#start_row int,
#limit_row int,
#column_name varchar(max),
#column_value varchar(max),
#sort_by varchar(max),
#order varchar(4)
)
as
begin
declare
#sql varchar(max) = ''
set #sql = 'SELECT * FROM ( '
+ 'SELECT ' + #table_primary_key + ', ROW_NUMBER() OVER (ORDER BY ' + #sort_by + ' ' + #order + ') as row FROM ' + #table_name + ' WHERE ' + #column_name + ' = ''' + #column_value + ''') a'
+ ' WHERE row > ' + cast(#start_row as varchar) + ' and row <= ' + cast(#limit_row as varchar)
exec ( #sql )
end
and then...
exec GetResults 'ProjectID', 'ProjectList', 10, 20, 'ProjectStatus', '5', 'ProjectName', 'ASC'
I have a lookup table with about 10 records, I know I can script the structure to a text file, but how can I script the data to insert into commands?
Ten records, and it's urgent?
Just type it out manually. Should be pretty easy to cut-n-paste.
Assuming SQL Server...
SQL Management Studio will generate an insert script. Right-click your database and select Tasks-Export data
This depends pretty much on the tools you are using...
The quick and dirty way is to run a select into a string and tell sql enterprise manager to give you text (not grid) as the output
SELECT 'INSERT INTO TABLES (fields here) VALUES (' + field1 + ', '....
Do something like this:
select "insert into my_targ_table(my_field_1, my_field_2, ..., my_field_n) values(" || x.my_field_1_col || ", " || x.my_field_2_col || ");"
from my_source_table x
Then just run the script you've generated.
This code works with all tables
DECLARE #TblName varchar(128)
DECLARE #WhereClause varchar(255)
DECLARE #cmd1 varchar(7000)
DECLARE #cmd2 varchar(7000)
SET #TblName = '<tablename>' --Name of your table
SET #WhereClause = ' ' --where clause ex columnA = 1
SET #cmd1 = 'SELECT '' INSERT INTO ' + #TblName + ' ( '
SET #cmd2 = ' + '' VALUES ( '' + '
create table #tableDef (id int identity (1,1), ColType int, ColName varchar(128))
--Fetch column names and datatypes
insert #tableDef (ColType, ColName)
select case when DATA_TYPE like '%char%' then 1
when DATA_TYPE like '%datetime%' then 2
else 0 end ,
COLUMN_NAME
from information_schema.columns
where TABLE_NAME = #TblName
order by ORDINAL_POSITION
SELECT #cmd1 = #cmd1 + ColName + ',',
#cmd2 = #cmd2
+ ' CASE WHEN ' + ColName + ' IS NULL '
+ ' THEN ''NULL'' '
+ ' ELSE '
+ case ColType
when 1 then ''''''''' + ' + ColName + ' + '''''''''
when 2 then ''''''''' + ' + 'CONVERT(VARCHAR(20),' + ColName + ')' + ' + '''''''''
else 'CONVERT(VARCHAR(20),' + ColName + ')' end
+ ' END + '','' + '
from #tableDef
order by id
select #cmd1 = left(#cmd1,len(#cmd1)-1) + ' ) '' '
select #cmd2 = left(#cmd2,len(#cmd2)-8) + '+'')'' FROM ' + #tblName + #WhereClause
select '/*' + #cmd1 + #cmd2 + '*/'
exec (#cmd1 + #cmd2)
drop table #tableDef