Simple SQL code in EXEC throwing an error - sql

This is in relation to my previous question. I am running a exec statement as below and I get an error Incorrect syntax near '+#dbname+'. Any help is greatly appreciated. Thanks.
exec('
declare #dbname nvarchar(100)
set #dbname = ''HUM_FM_1_SYNTQ_TEST''
select #dbname
Select seriesvariables_value from
(
select *, row_number() over
(order by SeriesVariables_ID asc) as rownum from ''+#dbname+''
.dbo.Seriesvariables where
SeriesVariables_Label = ''Enter Tablet Segment Pull Date'' and
Series_ID = 42) as tbl1
where rownum = 1')

It looks like you are trying to dynamically choose what database you're running this query on. You can do when you are creating the query your are going to exec, but you can't have a variable in your query that represents the database.
This should work
declare #dbname nvarchar(100)
set #dbname = 'HUM_FM_1_SYNTQ_TEST'
exec('
select #dbname
Select seriesvariables_value from
(
select *, row_number() over
(order by SeriesVariables_ID asc) as rownum from '+#dbname+'
.dbo.Seriesvariables where
SeriesVariables_Label = ''Enter Tablet Segment Pull Date'' and
Series_ID = 42) as tbl1
where rownum = 1')

Related

SQL return values if row count > X

DECLARE #sql_string varchar(7000)
set #sql_string = (select top 1 statement from queries where name = 'report name')
EXECUTE (#sql_string)
#sql_string is holding another SQL statement. This query works for me. It returns all the values from the query from the statement on the queries table. From this, I need to figure out how to only return the results IF the number of rows returned exceeds a threshold (for my particular case, 25). Else return nothing. I can't quite figure out how to get this conditional statement to work.
Much appreciated for any direction on this.
If all the queries return the same columns, you could simply store the data in a temporary table or table variable and then use logic such as:
select t.*
from #t t
where (select count(*) from #t) > 25;
An alternative is to try constructing a new query from the existing query. I don't recommend trying to parse the existing string, if you can avoid that. Assuming that the query does not use CTEs or have an ORDER BY clause, for instance, something like this should work:
set #sql = '
with q as (
' + #sql + '
)
select q.*
from q
where (select count(*) from q) > 25
';
That did the trick #Gordon. Here was my final:
DECLARE #report_name varchar(100)
DECLARE #sql_string varchar(7000)
DECLARE #sql varchar(7000)
DECLARE #days int
set #report_name = 'Complex Pass Failed within 1 day'
set #days = 5
set #sql_string = (select top 1 statement from queries where name = #report_name )
set #sql = 'with q as (' + #sql_string + ') select q.* from q where (select count(*) from q) > ' + convert(varchar(100), #days)
EXECUTE (#sql)
Worked with 2 nuances.
The SQL returned could not include an end ";" charicter
The statement cannot include an "order by" statement

Where clause concat with comma

I am trying to write what I thought would be a simple where clause. The FULLNAME string is formatted like this ("Doe, John"), hence the where clause and concat function.
Here is the query:
SELECT *
FROM table
WHERE concat(LAST_NM, ', ', FIRST_NM) = FULLNAME;
The query fails with the following error:
Error Executing Database Query. [Macromedia][SQLServer JDBC Driver]
[SQLServer]Incorrect syntax near ','.
Is your FullName something like "Doe, John"?
Is your FullName complete?
if not
SELECT *
FROM table
WHERE concat(LAST_NM, ', ', FIRST_NM) like ('%' + FULLNAME + '%')
Although I do not see anything wrong with your query, I would like to suggest a way to troubleshoot, by trying to find if it is a specific raw values that cause the concat function to break.
The idea is to iterate through the raws printing each one's values so you'll know which one (if at all) fails it, and it might be easier to take it from there to the next step.
--Copy your table data to a temporary table
--E.g.
SELECT *
into #table
FROM
(
select 'Doe' as LAST_NM , 'Jhon' as FIRST_NM
union
select 'Ryan' as LAST_NM , 'Jack' as FIRST_NM
union
select 'Dylan' as LAST_NM , 'Bob' as FIRST_NM
) a
--Iterate through the rows to see which one causes the issue
DECLARE #I INT = 1
DECLARE #TableCount INT = (select count(*) from #table)
DECLARE #FN varchar(100)
DECLARE #LN varchar(100)
WHILE #I <= #TableCount
BEGIN
SET #FN = (select Top 1 FIRST_NM from #table)
SET #LN = (select Top 1 LAST_NM from #table)
print(#I)
print(#FN)
print(#LN)
print('------------------')
delete top (1) from #table
SET #I = #I + 1
END

Scope of table when using with clause

Below is a piece of my stored proc.
I am getting error as invalid object MyCount, Please let me know where am going wrong
;With MyCount AS
(
Select DispatchToRegionId ,FolderNo, row_number() OVER(ORDER BY FolderNo DESC) as Row
from tblTransite where FolderNo = #VAL group by DispatchToRegionId,FolderNo
)
select #cnt = COUNT(*) from MyCount
if #cnt = 0
begin
set #InvalidFolderNo = #VAL
print 'cnt -' + cast(#cnt as varchar(max) ) + 'invalid folder - ' + cast(#InvalidFolderNo as varchar(max) )
return
end
select #Region =( Select top 1 DispatchToRegionId from MyCount
order by Row desc )
MSDN clearly states the following about the scope of a Common Table Expression (CTE):
A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement
Once you have run the first select query, you can no longer use the CTE for your next one. You may want to consider storing the data in a temporary table or table variable if you want to access it in multiple queries.
MyCount is available only for the first query after it. Try to select all you need in this one query:
;With MyCount AS
(
Select DispatchToRegionId ,FolderNo, row_number() OVER(ORDER BY FolderNo DESC) as Row
from tblTransite where FolderNo = #VAL group by DispatchToRegionId,FolderNo
)
SELECT
#cnt = (select COUNT(*) from MyCount),
#Region =( Select top 1 DispatchToRegionId from MyCount
order by Row desc )
if #cnt = 0
begin
set #InvalidFolderNo = #VAL
print 'cnt -' + cast(#cnt as varchar(max) ) + 'invalid folder - ' + cast(#InvalidFolderNo as varchar(max) )
return
end

How to use SQL ROW_NUMBER with INNER JOIN?

I have written this query to get data for special keyword:
ALTER procedure [dbo].[GetAllSpecialPaperTags]
#PKeyword nvarchar(200)
as
begin
select
Papers.PID, Papers.PTitle, Papers.PaperSummary
from
PaperKeywords
left join
PaperTags on PaperKeywords.PKeyID = PaperTags.PKeyID
left join
Papers on PaperTags.PID = Papers.PID
where
PaperKeywords.PKeyword = #PKeyword
end
I want use this article for custom paging : Custom Paging using SQL Server Stored Procedure
I wrote this query but I'm getting an error:
create procedure [dbo].[GetAllSpecialPaperTags]
#PageIndex INT = 1
,#PageSize INT = 10
,#RecordCount INT OUTPUT
,#PKeyword nvarchar(200)
as
BEGIN
SET NOCOUNT ON;
SELECT ROW_NUMBER() OVER
(
ORDER BY [Papers.PID] ASC
)AS RowNumber
,Papers.PID , Papers.PTitle , Papers.PaperSummary
INTO #Results
from PaperKeywords
left join PaperTags on PaperKeywords.PKeyID = PaperTags.PKeyID
left join Papers on PaperTags.PID = Papers.PID where PaperKeywords.PKeyword = #PKeyword
SELECT #RecordCount = COUNT(*)
FROM #Results
SELECT * FROM #Results
WHERE RowNumber BETWEEN(#PageIndex -1) * #PageSize + 1 AND(((#PageIndex -1) * #PageSize + 1) + #PageSize) - 1
DROP TABLE #Results
end
Error:
Msg 207, Level 16, State 1, Procedure GetAllSpecialPaperTags, Line 11
Invalid column name 'Papers.PID'.
Why?
This is your order by expression:
ORDER BY [Papers.PID] ASC
It is looking for a column named in its entirety "Papers.PID". It is not looking for the PID column in Papers. Just drop the braces:
ORDER BY Papers.PID ASC

Dynamic sql using table variable -TSQL

My problem is using a table variable in a exec.
declare #sort_col nvarchar(1000) = 'itm_id'
declare #sort_dir nvarchar(4) = 'desc'
declare #filters nvarchar(1000) = ' and itm_name like ''%aa%'''
declare #temp table
(
itm_id int
)
insert into #temp
EXEC('select itm_id from Tblitm where itm_name not like ''%aa%''')
EXEC('select * from (select (ROW_NUMBER() OVER (ORDER BY '+#sort_col+' '+#sort_dir+')) row_num, * FROM (select itm_id, itm_name,
dbo.fnItmsHistory(itm_id) itm_history
from dbo.Tblitm as itm
left outer join '+#temp+' as temp on itm.itm_id = temp.itm_id
where itm_id=itm_id and temp.itm_id = null '+#filters+') as x) as tmp')
It says Must declare the scalar variable "#temp" when the temp table is declared i tried using original temp table and it worked, but i had problems when trying to update my entity model.So is there any solution for this problem?
Note:
I must use exec because in filters i store string for the where clause.
Try moving the table variable inside the dynamic statement.
EXEC('
declare #temp table
(
itm_id int
)
insert into #temp
select itm_id from Tblitm where itm_name not like ''%aa%''
select * from (select (ROW_NUMBER() OVER (ORDER BY '+#sort_col+' '+#sort_dir+')) row_num, * FROM (select itm_id, itm_name,
dbo.fnItmsHistory(itm_id) itm_history
from dbo.Tblitm as itm
left outer join #temp as temp on itm.itm_id = temp.itm_id
where itm_id=itm_id and temp.itm_id = null '+#filters+') as x) as tmp')
For solution i had to use a temp table and then on the start of my stored procedure i used the if condition from the EF can't infer return schema from Stored Procedure selecting from a #temp table anwser.
It's the best solution for this scenario i think.