Error on INSERT INTO SELECT in query hosted on variable - sql-insert

I'm a little bit conffused.
Can anyone tell me why i get sintaxis error on the next script?
declare #schema1 NVARCHAR(100)
set #schema1 = 'ex.:DATABASENAME'
declare #query NVARCHAR(500)
set #query = 'INSERT UsersSessions (UserSessionId, IpAddress, ChannelId, IsEmployee, UserId, ClientFullName, UserAgent, StartDate, ExpirationDate, SessionDuration)
SELECT us.UserSessionId, us.IpAddress, us.ChannelId, CASE WHEN us.ChannelId = 2 THEN 1 ELSE 0 END AS IsEmployee, us.UserId, (u.Name + u.LastName) as ClientFullName, us.UserAgent, us.StartDate, us.ExpirationDate, (us.ExpirationDate-us.StartDate) AS SessionDuration
FROM ' + #schema1 + '.UsersSessions us INNER JOIN ' + #schema1 + '.Users u ON us.UserId = u.UserId WHERE us.UserSessionId NOT IN (SELECT UserSessionId FROM UsersSessions)'
EXEC(#query)
RESULT:
Msg 156, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'Use'.
Completion time: 2021-11-16T11:10:32.6309920-03:00
If i remove the Insert block, i get the script running
declare #schema1 NVARCHAR(100)
set #schema1 = 'ex.:DATABASENAME'
declare #query NVARCHAR(500)
set #query = '
SELECT us.UserSessionId, us.IpAddress, us.ChannelId, CASE WHEN us.ChannelId = 2 THEN 1 ELSE 0 END AS IsEmployee, us.UserId, (u.Name + u.LastName) as ClientFullName, us.UserAgent, us.StartDate, us.ExpirationDate, (us.ExpirationDate-us.StartDate) AS SessionDuration
FROM ' + #schema1 + '.UsersSessions us INNER JOIN ' + #schema1 + '.Users u ON us.UserId = u.UserId WHERE us.UserSessionId NOT IN (SELECT UserSessionId FROM UsersSessions)'
EXEC(#query)
RESULT:
(1 row affected)
Completion time: 2021-11-16T11:11:07.6741062-03:00
I think some char is missing?
Thanks and regards!

Your query variable length is not sufficient, modify it as below. Also, schema name can accept only certain characters, colon is not allowed I guess.
declare #query NVARCHAR(max)

Related

FakeFunction Results based on Test

I'm using tSqlt to unit test a stored procedure. This stored proc joins to a table-valued function, the function takes no parameters and the results are filtered via the join on clause.
I'm writing multiple tests for the stored proc. Is there a way to to fake the function in such a way that I could return different results based on the test that is being run.
The only solution I can think of is to create a fake per test, which is possible but a little more than clunky.
I imagine an ideal solution would be some sort of variable exposed in tsqlt that would allow me to determine which test I'm in and use some sort of case statement or something.
I use following procedure for that. It is not ideal, but working:
CREATE PROCEDURE [tSQLt].[FakeFunction2]
#FunctionName VARCHAR(200)
, #SchemaName VARCHAR(200) = 'dbo'
, #tmpTableName VARCHAR(200)
AS
BEGIN
DECLARE #Params VARCHAR(2000);
DECLARE #NewName VARCHAR(MAX) = #FunctionName + REPLACE(CAST(NEWID() AS VARCHAR(100)), '-', '');
DECLARE #FunctionNameWithSchema VARCHAR(MAX) = #SchemaName + '.' + #FunctionName;
DECLARE #RenameCmd VARCHAR(MAX) = 'EXEC sp_rename ''' + #FunctionNameWithSchema + ''', ''' + #NewName + ''';';
DECLARE #newTbleName VARCHAR(200) = #SchemaName + '.tmp' + REPLACE(CAST(NEWID() AS VARCHAR(100)), '-', '');
DECLARE #newTblStmt VARCHAR(2000) = 'SELECT * INTO ' + #newTbleName + ' FROM ' + #tmpTableName;
EXEC tSQLt.SuppressOutput #command = #newTblStmt;
SELECT #Params = p.params
FROM
( SELECT DISTINCT ( SELECT p1.name + ' ' + type1.name + b.brk + ',' AS [text()]
FROM sys.types type1
JOIN sys.parameters p1 ON p1.system_type_id = type1.system_type_id
CROSS APPLY
( SELECT CASE WHEN type1.name LIKE '%char' OR type1.name = 'varbinary' THEN
REPLACE(
'(' + CAST(p1.max_length AS VARCHAR(5)) + ')', '-1', 'MAX')
WHEN type1.name IN ('decimal', 'numeric') THEN
'(' + CAST(p1.precision AS VARCHAR(5)) + ', '
+ CAST(p1.scale AS VARCHAR(5)) + ')'
WHEN type1.name IN ('datetime2') THEN
'(' + CAST(p1.scale AS VARCHAR(5)) + ')'
ELSE ''
END AS brk) b
WHERE p1.object_id = p.object_id
ORDER BY p1.parameter_id
FOR XML PATH('')) [parameters]
FROM sys.objects AS o
LEFT JOIN sys.parameters AS p ON p.object_id = o.object_id
LEFT JOIN sys.types AS t ON t.system_type_id = p.system_type_id
WHERE o.name = #FunctionName AND o.schema_id = SCHEMA_ID(#SchemaName)) [Main]
CROSS APPLY
(SELECT LEFT(Main.[parameters], LEN(Main.[parameters]) - 1) params) AS p;
EXEC tSQLt.SuppressOutput #command = #RenameCmd;
DECLARE #newFunctionStmt VARCHAR(MAX) = '';
SET #newFunctionStmt = 'CREATE FUNCTION [' + #SchemaName + '].[' + #FunctionName + '](' + COALESCE(#Params,'') + ')';
SET #newFunctionStmt = #newFunctionStmt + ' RETURNS TABLE AS RETURN (SELECT * FROM ' + #newTbleName + ');';
EXEC tSQLt.SuppressOutput #command = #newFunctionStmt;
END;
and usage:
INSERT INTO #table
(col1
, col2
, col3)
VALUES
('a', 'b', 'c'),
('d', 'e', 'f');
EXEC tSQLt.FakeFunction2 #FunctionName = 'function_name'
, #SchemaName = 'dbo'
, #tmpTableName = '#table';
now with any passed parameter to that function it will always return the values from #table temp table
I thought of one potential solution.
I create a table within the test class schema and populate it with the results I wish to be returned per test.
CREATE TABLE testcalass.fakefunction_Results
(
ID INT,
Value NUMERIC(12, 5)
)
GO
CREATE FUNCTION testcalass.fakefunction()
RETURNS #results TABLE
(
ID INT,
Value NUMERIC(12, 5)
)
BEGIN
INSERT INTO #results
SELECT ID, Value FROM testcalass.fakefunction_Results
END
GO
So basically, I can populate is functions results at the top of my tests during the assemble section.

dynamic query showing 'Unclosed quotation mark after the character string '),

i have a stored procedure in which i am getting error 'Unclosed quotation mark after the character string ' having a hard time with the script. please help me to find out what is wrong in my code.
here is my code.
ALTER PROCEDURE [dbo].[usp_Transfer]
#orgid bigint,
#SearchString nvarchar (500) = null,
#LocationId bigint = 0,
#ownerid bigint,
#OrderList varchar(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.\
SET NOCOUNT ON;
DECLARE #SQL varchar(MAX)
BEGIN
SET #SQL = 'SELECT ProductID = ii.ProductId,
InvItemId = convert(bigint,0),Name = p.Name,
PrimaryImageID = p.PrimaryImageID,ProductNumberLabel = p.ProductNumberLabel,ProductNumber = p.ProductNumber,
category = isnull(c.Name,''),
qty = ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00),
SalePrice= ISNULL(p.SalePrice, 0.00),
EnteredQuantity=(case when (ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) > 1) then 1.00 else ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) end)
,Discount=0,u.UnitName,
u.UnitID
FROM dbo.[Inven] ii
Left Join dbo.[Product] p on ii.ProductId = p.ProductId and p.activestatus=1
Left Join dbo.[category] c on p.DefaultCategoryId = c.CategoryId
Left Join dbo.[Unit] u on p.UnitId=u.UnitId and u.Activestatus=1
WHERE p.OrganizationID = #orgid
AND ii.InventoryID IN(1634)
AND ii.ActiveStatus = 1
AND p.ActiveStatus = 1
AND p.IsDisabled = 0
And p.CanSale = 1
AND ii.InventoryID IN (' + #OrderList + ')
group by ii.ProductId, p.Name, p.PrimaryImageID, p.ProductNumberLabel, p.ProductNumber, c.Name,p.SalePrice,u.unitname,u.UnitID
having ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0) > 0
Order by p.ProductNumber, p.Name, c.Name '
--EXEC(#SQL)
PRINT(#SQL)
END
END
Two things of note.
First, does #OrderList contain any quotes?
Second, this line:
...' WHERE p.OrganizationID = #orgid '
Should be:
....'WHERE p.OrganizationID = ' + #orgid + '...'
The easy way to test if either of these are the cause of the problem is to comment both out, run it and see if it works, if it does then comment them in one at a time to see which one gives you the error.
Finally, you could rewrite this query and avoid using a dynamic query at all. I guess looking at the query you have done it because of the IN (' + #OrderList + ') clause. These posts might help you rework that section:
Parameterize an SQL IN clause
SQL Server - In clause with a declared variable
Update your SP as below:
Note: there are so many errors if solve one like quotation mark, declare variable #orgid and then conversion error
Your initial error due to : category = isnull(c.Name,''), replace it with category = isnull(c.Name,'''')
alter PROCEDURE [dbo].[usp_Transfer]
#orgid bigint=1,
#SearchString nvarchar (500) = null,
#LocationId bigint = 0,
#ownerid bigint=1,
#OrderList varchar(MAX)='1'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.\
SET NOCOUNT ON;
DECLARE #SQL varchar(MAX)
BEGIN
SET #SQL = 'SELECT ProductID = ii.ProductId,
InvItemId = convert(bigint,0),Name = p.Name,
PrimaryImageID = p.PrimaryImageID,ProductNumberLabel = p.ProductNumberLabel,ProductNumber = p.ProductNumber,
category = isnull(c.Name,''''),
qty = ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00),
SalePrice= ISNULL(p.SalePrice, 0.00),
EnteredQuantity=(case when (ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) > 1) then 1.00 else ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) end)
,Discount=0,u.UnitName,
u.UnitID
FROM dbo.[Inven] ii
Left Join dbo.[Product] p on ii.ProductId = p.ProductId and p.activestatus=1
Left Join dbo.[category] c on p.DefaultCategoryId = c.CategoryId
Left Join dbo.[Unit] u on p.UnitId=u.UnitId and u.Activestatus=1
WHERE p.OrganizationID = '+CAST(#orgid AS VARCHAR(10))+'
AND ii.InventoryID IN(1634)
AND ii.ActiveStatus = 1
AND p.ActiveStatus = 1
AND p.IsDisabled = 0
And p.CanSale = 1
AND ii.InventoryID IN (' + #OrderList + ')
group by ii.ProductId, p.Name, p.PrimaryImageID, p.ProductNumberLabel, p.ProductNumber, c.Name,p.SalePrice,u.unitname,u.UnitID
having ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0) > 0
Order by p.ProductNumber, p.Name, c.Name '
EXEC(#SQL)
PRINT(#SQL)
END
END

How to separate (split) string with comma in SQL Server stored procedure

I have a checkboxlist. The selected (checked) items are stored in List<string> selected.
For example, value selected is monday,tuesday,thursday out of 7 days
I am converting List<> to a comma-separated string, i.e.
string a= "monday,tuesday,thursday"
Now, I am passing this value to a stored procedure as a string. I want to fire query like:
Select *
from tblx
where days = 'Monday' or days = 'Tuesday' or days = 'Thursday'`
My question is: how to separate string in the stored procedure?
If you pass the comma separated (any separator) string to store procedure and use in query so must need to spit that string and then you will use it.
Below have example:
DECLARE #str VARCHAR(500) = 'monday,tuesday,thursday'
CREATE TABLE #Temp (tDay VARCHAR(100))
WHILE LEN(#str) > 0
BEGIN
DECLARE #TDay VARCHAR(100)
IF CHARINDEX(',',#str) > 0
SET #TDay = SUBSTRING(#str,0,CHARINDEX(',',#str))
ELSE
BEGIN
SET #TDay = #str
SET #str = ''
END
INSERT INTO #Temp VALUES (#TDay)
SET #str = REPLACE(#str,#TDay + ',' , '')
END
SELECT *
FROM tblx
WHERE days IN (SELECT tDay FROM #Temp)
Try this:
CREATE FUNCTION [dbo].[ufnSplit] (#string NVARCHAR(MAX))
RETURNS #parsedString TABLE (id NVARCHAR(MAX))
AS
BEGIN
DECLARE #separator NCHAR(1)
SET #separator=','
DECLARE #position int
SET #position = 1
SET #string = #string + #separator
WHILE charindex(#separator,#string,#position) <> 0
BEGIN
INSERT into #parsedString
SELECT substring(#string, #position, charindex(#separator,#string,#position) - #position)
SET #position = charindex(#separator,#string,#position) + 1
END
RETURN
END
Then use this function,
Select *
from tblx
where days IN (SELECT id FROM [dbo].[ufnSplit]('monday,tuesday,thursday'))
try this
CREATE FUNCTION Split
(
#delimited nvarchar(max),
#delimiter nvarchar(100)
) RETURNS #t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id int identity(1,1), -- I use this column for numbering splitted parts
val nvarchar(max)
)
AS
BEGIN
declare #xml xml
set #xml = N'<root><r>' + replace(#delimited,#delimiter,'</r><r>') + '</r></root>'
insert into #t(val)
select
r.value('.','varchar(max)') as item
from #xml.nodes('//root/r') as records(r)
RETURN
END
GO
usage:
select * from tblx where days in (select val from dbo.split('monday,tuesday,thursday',','))
I think you want this
SELECT * FROM tblx where days in ('Monday','Tuesday','Thursday')
you can get it like this:
var a = "monday,tuesday,thursday";
var sql = string.Format("Select * from tblx where days IN ('{0}')", string.Join("','",a.Split(new[] {','})));
I face the same problem, and i try all the way but not get expected solution. Finally i did like follow. Try it hope it will work...
create Function [dbo].[Split]
(
#RowData NVARCHAR(MAX),
#SplitOn NVARCHAR(5)
)
RETURNS #RtnValue TABLE
(
Id INT IDENTITY(1,1),
Data NVARCHAR(100)
)
AS
BEGIN
DECLARE #Cnt INT
SET #Cnt = 1
WHILE (Charindex(#SplitOn,#RowData)>0)
BEGIN
INSERT INTO #RtnValue (data)
SELECT Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
SET #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
SET #Cnt = #Cnt + 1
END
INSERT INTO #RtnValue (data)
SELECT Data = ltrim(rtrim(#RowData))
RETURN
END
And in the store procedure put the code like that.
select #ActualTarget= count(*) from UpdateVisitDetails where CreatedBy IN (SELECT [DATA] FROM [dbo].[Split](#AllDATS,',' ))
I have same problem. I tried this.. and this was properly run
ALTER FUNCTION [dbo].[Split]
(
#List varchar(max),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Value nvarchar(max)
)
AS
BEGIN
IF (len(#List) <=0)
Begin
Return
End
While (Charindex(#SplitOn,#List)>0)
Begin
Insert Into #RtnValue (value)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#SplitOn,#List)-1)))
Set #List = Substring(#List,Charindex(#SplitOn,#List)+len(#SplitOn),len(#List))
End
Insert Into #RtnValue (Value)
Select Value = ltrim(rtrim(#List))
Return
END
Run :
SELECT * FROM dbo.Split('Apple,Banana,Mango',',')
Output:

sql create table with stored procedure with optional parameters

I am writing a report based on parameters, utilizing a sql stored procedure. Problem is there are several 'optional' parameters, where the user can choose a value, or ignore that parameter altogether. I need to use the stored proc as a dataset in asp.net report. Only way I thought of doing it is to create a table from the results. But I'm clueless.
How do I turn this into a 'create table' stored proc?
Any assistance is greatly appreciated.
Cindy
This is what I have so far -
ALTER PROCEDURE [dbo].[rspSCL]
-- Add the parameters for the stored procedure here
(#year as int,
#RRID as int,
#State as nchar(2),
#Sub as varchar(75),
#app as int,
#sprayed as int,
#subcontracted as int,
#thirdapp as bit)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #SQL as varchar(4000)
DECLARE #SUBQ AS varchar(400)
--what fields need to be seen
SET #SQL = 'SELECT C.CRID, C.DOT, C.RR, C.Pref, C.MP, C.Division, C.Subdivision,C.City, C.Street,
C.State, C.County, C.RestrictedCounty, C.Remarks, C.SpecialInstructions, C.Route, C.ThirdAppRequired,
C.MainTrks, C.OtherTrks, C.OnSpur, C.MaxSpeed, C.SubContracted, C.FenceEncroachment, C.Lat, C.Long,
C.PropertyType, C.WarningDevice,C.Surface, C.ROWNE, C.ROWNW, C.ROWSE, C.ROWSW, C.ROWWidth, C.ExtNE,
C.ExtNW, C.ExtSE, C.ExtSW, C.TempActive, A.Spray, A.ContractYear'
SET #SUBQ =
CASE WHEN #app = 1 THEN
'FROM Crossings LEFT OUTER JOIN
(select A.CRID, A.spray FROM ApplicationData A
WHERE A.ContractYear = ' + CAST( #year AS varchar(4)) + ') as APPS
ON Crossings.CRID = APPS.CRID'
WHEN #app = 2 THEN
'FROM Crossings inner join
(SELECT crid, C,OUNT(APPID)as count
from ApplicationData
where ContractYear = ' + CAST( #year AS varchar(4)) + '
group by CRID) as APPS
ON Crossings.CRID = APPS.CRID
WHERE Crossings.RR = '+ CAST( #RRID AS varchar(4)) + '
and crossings.state = '+ #state + '
and count = 1'
when #app = 3 THEN
'FROM Crossings inner join
(SELECT crid, COUNT(APPID)as count
from ApplicationData
where ContractYear = ' + CAST( #year AS varchar(4)) + '
group by CRID) as APPS
ON Crossings.CRID = APPS.CRID
WHERE Crossings.RR = '+ CAST( #RRID AS varchar(4)) + '
and crossings.state = '+ #state + '
and count = 2'
ELSE ''
END
--add the FROM to the query
SET #SQL = #SQL + #SUBQ
--add the subdivision to the where statement
If #Sub != 'ALL'
SET #SQL = #SQL + 'AND (C.Subdivision = ' + #Sub + ')'
ELSE
SET #SQL = #SQL
--add sprayed to where
DECLARE #S as varchar(100)
SET #S =
CASE WHEN #sprayed = 1 THEN
'AND (A.sprayed = 1)'
WHEN #sprayed = 0 THEN
'AND (A.sprayed = 0)'
ELSE
''
END
SET #SQL = #SQL + #S
--add subcontracted to where
DECLARE #C as varchar (100)
SET #C =
CASE WHEN #subcontracted = 0 THEN
'AND (C.subcontracted = 0)'
WHEN #subcontracted = 1 THEN
'AND (C.subcontracted = 1)'
ELSE
''
END
SET #SQL = #SQL + #C
IF #thirdapp = 1
SET #SQL = #SQL + 'AND (C.ThirdAppRequired = 1)'
ELSE
SET #SQL = #SQL
END

Paging in my web page

I have a large data set and i have to apply paging on that data set and after that the result set should be another data set. What is the reliable method to achieve that.
I have tried with 'PagedDataSource' class but i don't know how it is possible to convert to dataset or data table.
In my case i need a general solution. I have to bind to a control like gridview as well as i have to used it with normal html table.
check this article doing same thing you want : http://www.codeproject.com/KB/custom-controls/EnhanceGrid.aspx
following sp returns record that you want
CREATE PROCEDURE [dbo].[GetRequestedRecordByPage]
#FromList nvarchar(200) -- Table Name
,#SortingCol nvarchar(200) -- Sorting column Name
,#SelectList nvarchar(200) = '*' -- Select columns list
,#WhereClause nvarchar(200) = '' -- Where clause i.e condition
,#PageNum int = 1 -- Requested page number
,#PageSize int = 5 -- No of record in page
,#TotalNoOfRecord int output -- Total no of selected records
AS
Begin
SET NOCOUNT ON
DECLARE #Query nvarchar(max) -- query going to be execute
IF rtrim(ltrim(#WhereClause)) <> ''
BEGIN
SET #Query ='SELECT #TotalNoOfRecord = COUNT(*)
FROM ' + #FromList + '
WHERE ' + #WhereClause
END
ELSE
BEGIN
SET #Query ='SELECT #TotalNoOfRecord = COUNT(*)
FROM ' + #FromList
END
/* Count no. of record */
EXEC sp_executeSQL
#Query,
#params = N'#TotalNoOfRecord INT OUTPUT',
= #TotalNoOfRecord OUTPUT
DECLARE #lbound int, #ubound int
/* Calculating upper and lower bound */
SET #lbound = ((#PageNum - 1) * #PageSize)
SET #ubound = #lbound + #PageSize + 1
/* Get list of record(s) */
SELECT #Query = ''
SELECT #Query = 'SELECT *
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ' + #SortingCol + ') AS rownumber,' +#SelectList +
' FROM ' + #FromList
IF rtrim(ltrim(#WhereClause)) <> ''
BEGIN
SELECT #Query = #Query + ' WHERE ' + #WhereClause
END
SELECT #Query = #Query + ' ) AS tbl
WHERE rownumber > ' + CONVERT(varchar(9), #lbound) +
' AND rownumber < ' + CONVERT(varchar(9), #ubound)
EXEC (#Query)
End

Resources