dynamic sql count in a variable - sql

This query works
select #V_COUNT =COUNT(1) from TAB1
But I want to pass the table as variable how to do that in sybase ?
i tried this but didnt work
select #V_COUNT ='COUNT(1) from ''||#TMP_TABLE_NAME||'''
select #LL_COUNT = CONVERT(numeric(30),#V_COUNT)
edit:
i did this
SELECT #V_COUNT ='SELECT COUNT(1) from '+ #TABLE_NAME
execute (#V_COUNT)
SELECT #LL_COUNT = 'SELECT convert(NUMERIC(6),'||#V_COUNT||')'
Implicit conversion from datatype 'VARCHAR' to 'NUMERIC' is not
allowed. Use the CONVERT function to run this query.

You need to execute that dynamic query, using:
CREATE TABLE #Count(x int)
SELECT #sSQL = "INSERT #Count SELECT COUNT(1) from "+ #TMP_TABLE_NAME
execute (#sSQL)
SELECT #V_COUNT = x from #Count
DROP TABLE #Count
SELECT #LL_COUNT = (SELECT convert(NUMERIC(30,4), #V_COUNT))
SELECT #LL_COUNT
where #TMP_TABLE_NAME might be SELECT #TMP_TABLE_NAME = 'tablename' is simple string which you don't need to execute or get result from.

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

nested select query with table name in sqlite

I am trying to select all distinct values from all tables that start with a specific name, like: 'logs_2020_12_01', 'logs_2021_01_02', ..To select all tables with this specific name is straight forward:
SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'logs_%';
The select I want for one individual table is:
SELECT DISTINCT batch FROM logs_2021_01_27;
but I cannot find a way to combine it to make the selection from all tables. I tried a couple of things but it does not work, like:
SELECT DISTINCT batch FROM (SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'logs_%')
any ideas?
thanks
What about using Dynamic SQL, stored your tables information into a temp table with id column and set it to identity.
CREATE TABLE #temp ---identity column will be used to iterate
(
id INT IDENTITY,
TableName VARCHAR(20)
)
INSERT INTO #temp
SELECT name FROM sqlite_master WHERE type='table' AND name LIKE 'logs_%';
-- choose your own results with where conditions
DECLARE #SQL VARCHAR(MAX)
DECLARE #Count INT = 1
DECLARE #Table VARCHAR(20)
WHILE #COUNT <= (SELECT COUNT(*) FROM #temp)
BEGIN
select #table = TABLENAME FROM #temp WHERE id = #Count
SELECT #sql = 'SELECT DISTINCT(batch) FROM '+ #table
PRINT #SQL
SET #Count = #Count + 1
END
after your print result looks good, change it to EXEC(#SQL), thanks
SQLite does not support dynamic sql.
You have to select the column batch from each of all the tables and combine them with UNION so the duplicates are removed:
SELECT batch FROM logs_2020_12_01 UNION
SELECT batch FROM logs_2020_12_02 UNION
......................................
SELECT batch FROM logs_2020_12_30 UNION
SELECT batch FROM logs_2020_12_31
If you don't know the full names of the tables, you can get them with this statement:
SELECT name
FROM sqlite_master
WHERE type = 'table' AND name LIKE 'logs/_%' ESCAPE '/'
and then use a programming language to construct a SELECT statement with UNION to get the results that you want.

Numeric value is not recognized error in OPENQUERY

I have the following stored procedure. When it runs, i get the error
returned message "Numeric value '+#requestno+' is not recognized" . I believe the setting of the variable requestno is not working. How do i resolve it?
Declare #requestno nvarchar(max)
Set #requestno = (Select requestno from table1 where condition met)
SELECT * INTO tempdb..#temptable FROM OPENQUERY (SalesDb,
'SELECT *
FROM TableinAnotherDb
WHERE 1=1
and request_number=''+#requestno+'' Order by some column'
)
Thank you
prepare you query in advance:
Declare #queryStr nvarchar(max)
SELECT #queryStr ='SELECT *
FROM TableinAnotherDb
WHERE 1=1
and request_number='+ requestno+' Order by some column'
FROM table1
WHERE condition met
SELECT * INTO tempdb..#temptable FROM OPENQUERY (SalesDb,#queryStr)

SQL: SAP Hana if parameter is null, ignore where

I'm passing 3 parameters into my Hana Stored Procedure to use as WHERE clauses, and if the parameter is null, I want the procedure to behave as though that condition doesn't exist.
example:
if one of the input parameters is deviceType.
SELECT TOP 5 DISTINCT USERS FROM MYTABLE
WHERE USERDEVICE = deviceType;
if deviceType is null, query should simply be
SELECT TOP 5 DISTINCT USERS FROM MYTABLE.
I know I can achieve this with if statements, but is there another way to do it?
Basically, the requirement is to not apply any condition is deviceType IS NULL. Instead of altering the query dynamically, you could just construct a condition that always returns true in such a situation by using the logical or operator:
SELECT TOP 5 DISTINCT USERS
FROM MYTABLE
WHERE deviceType IS NULL OR USERDEVICE = deviceType;
When using SQLScript you can use the APPLY_FILTER() function.
E.g.
drop procedure getTopUsers;
create procedure getTopUsers (IN filter_cond NVARCHAR(200)) as
begin
vUsers = SELECT DISTINCT user_name, creator FROM USERS;
if (:filter_cond is NULL) then
TopUsers = select TOP 5 user_name FROM :vUsers;
else
tTopUsers = APPLY_FILTER(:vUsers, :filter_cond);
TopUsers = SELECT TOP 5 user_name FROM :tTopUsers;
end if;
SELECT user_name FROM :TopUsers;
end;
call getTopUsers ('CREATOR != ''SYS'' ');
call getTopUsers (NULL);
DECLARE #deviceType VARCHAR(100)
DECLARE #SQL VARCHAR(256)
,#sql1 VARCHAR(256) = 'WHERE USERDEVICE = ''' + #deviceType + ''''
SET #SQL = 'SELECT TOP 5 DISTINCT USERS FROM MYTABLE'
SET #SQL = CASE
WHEN #deviceType IS NULL
THEN #SQL
ELSE #SQL + ' ' + #sql1
END
EXEC (#SQL)

Calling table-valued-function for each result in query

Say I had a query like this:
SELECT X FROM Table WHERE Y = 'Z'
How could I execute a Stored Procedure using each X from the above query as the parameter?
UPDATE
I have changed the SP to be a Table-valued function instead. So for each call to the function it will return a table. What I need to do is store all these results in perhaps a temp table and have my SP return this table.
SOLUTION
Finally managed to get this to work with some help from #cyberkiwi. Here is my final solution:
DECLARE #Fields TABLE (
Field int)
INSERT INTO #Fields (X) SELECT * FROM tvf_GetFields(#SomeIdentifier)
SELECT * FROM #Fields
CROSS APPLY dbo.tvf_DoSomethingWithEachField([#Fields].Field)
You can generate a batch statement out of it and then EXEC it
DECLARE #sql nvarchar(max)
SELECT #sql = coalesce(#sql + ';', '')
+ 'exec sprocname ' + QuoteName(AField, '''')
FROM Table
WHERE AField2 = 'SomeIdentifier'
AND AField is not null
EXEC (#sql)
Before the edit (to TVF), you could have changed the SP to continue to populate a temp table.
Post-edit to TVF, you can use a cross apply:
SELECT F.*
FROM Tbl CROSS APPLY dbo.TVFName(Tbl.AField) F
WHERE Tbl.AField2 = 'SomeIdentifier'
Which returns all the "table results" from each invocation of Tbl.AField into a single result set