Add filtering on top of Stored Procedure - sql

Currently I am dynamically building a SQL SELECT statement that has filters at the end based on a users selections in three different ListBoxes.
So I end up having...
SELECT
whatever
FROM
dbo.Table
WHERE
(columnA = listB1.Item[x] OR columnA = listB1.Item[y])
AND
(columnB = listB2.Item[g] OR columnA = listB2.Item[h])
....
What I want to do is store the SELECT ... FROM ... as a stored procedure, and then use the remaining WHERE... portion as a parameter I guess.
I tried experimenting in SQL Server Management Studio to see if I could just create a stored procedure with a parameter at the end...
SELECT whatever
FROM dbo.Table #PARAM
... where PARAM = 'WHERE ... and ... or ' and it didn't like that.
Is it possible to grab a stored procedure, open up the actual content of it, and concatenate my WHERE... onto the end of it?
Thanks. I'm no DB expert, so any other ways of doing this would greatly be appreciated.
EDIT: I should add that the AND / OR combination statements are variable.
So one time it could be
SELECT whatever
FROM dbo.TABLE
<no filter>
or
SELECT whatever
FROM dbo.TABLE
WHERE (colA = this)
AND (colB = that)
or
SELECT whatever
FROM dbo.TABLE
WHERE (colA = this OR colA = that OR colA = who)
AND (colC = him)

You can do this by using dynamic queries in stored procedure. Create SP with static select query and pass the where clause as parameter.
CREATE PROCEDURE SP_GetFromDB
(
#Param VARCHAR(200)
)
AS
BEGIN
DECLARE #Query VARCHAR(2000) = ''
SELECT #Query = 'SELECT Column1, Column2, * FROM dbo.MyTable
WHERE ' + #Param
EXECUTE (#Query)
END
In application side, form a string for where clause something like
string query = "(columnA = " + listB1.Item[x] + " OR columnA = " + listB1.Item[y] ") AND (columnB = " + listB2.Item[g] + " OR columnA = " + listB2.Item[h] ")" ;
and pass this as #param for the Stored Procedure.

Create the proc and pass in the users selections as parameters.
CREATE PROCEDURE YourNewSP (x,y,g,h)
as
begin
SELECT whatever FROM dbo.Table
WHERE (columnA = x OR columnA = y)
AND
(columnB = g OR columnA = h)
end

Since SQL Server 2008 you can pass table valued parameters to stored procedures.
So, for each of your list boxes, you could add one table valued parameter.
Then use a WHERE like
WHERE columnA IN(SELECT theValue FROM #listBoxAValues)
AND columnB IN(SELECT theValue FROM #listBoxBValues)
AND columnC IN(SELECT theValue FROM #listBoxCValues)
To get around the case that there are no values provided for any of the three parameters you can pre-check it like
DECLARE #CountA BIT = (SELECT count(*) FROM #listBoxAValues)
DECLARE #CountB BIT = (SELECT count(*) FROM #listBoxBValues)
DECLARE #CountC BIT = (SELECT count(*) FROM #listBoxCValues)
and then rewrite the WHERE like
WHERE (#CountA = 0 OR columnA IN(SELECT theValue FROM #listBoxAValues))
AND (#CountB = 0 OR columnB IN(SELECT theValue FROM #listBoxBValues))
AND (#CountC = 0 OR columnC IN(SELECT theValue FROM #listBoxCValues))
To be able to pass a table valued parameter you have to create a new table valued type in your database first:
CREATE TYPE MyType AS TABLE(theValue int);
Given all your three list boxes could use the same type, your stored procedure would start like
CREATE PROCEDURE dbo.pr_myProc (
#listBoxAValues MyType,
#listBoxBValues MyType,
#listBoxCValues MyType)

Related

Returning a table in firebird 3.0 with stored function or stored procedure

I'm trying to write a stored procedure/function that returns me a table with one or multiple rows of data.
The returned data depends on a variable shown in the following sql statement:
SELECT * FROM table_name AS SD WHERE EXISTS
(SELECT DISTINCT S.PARENT_ID FROM table_name AS S
WHERE S.COMPONENT_ID = 10011 AND S.CARRIER_GROUP_ID = X AND SD.SD_ID = S.PARENT_ID)
So far I have seen that something is done like this:
CREATE FUNCTION f_test_function (X INT)
RETURNS TABLE
AS
RETURN
(SELECT * FROM table_name AS SD WHERE EXISTS
(SELECT DISTINCT S.PARENT_ID FROM table_name AS S
WHERE S.COMPONENT_ID = 10011 AND S.CARRIER_GROUP_ID = X AND SD.SD_ID = S.PARENT_ID));
Afterwards you call the function/procedure with a X value. I know that there is something wrong with the returns type but I don't know what.
Can anyone help?
What you are looking for is a selectable stored procedure. Firebird requires you to explicitly declare the columns the stored procedure returns, so something like returns table is not an option. For example:
create procedure sp_test_procedure (x integer)
returns (column1 integer, column2 varchar(50))
as
begin
for select value1, value2
from table_name SD
where exists (
SELECT DISTINCT S.PARENT_ID
FROM table_name AS S
WHERE S.COMPONENT_ID = 10011
AND S.CARRIER_GROUP_ID = :X
AND SD.SD_ID = S.PARENT_ID)
into column1, column2
do
begin
suspend;
end
end
You will need to explicitly map the columns, so a simple select * is not a good idea.
Note the use of for select, which selects zero or more rows and iterates over the cursor, and suspend, which outputs a row to be fetched from the stored procedure (in this case for each row of the cursor).
You can produce values from this procedure like:
select column1, column2
from sp_test_procedure(10)

SQL select statement with WHERE clause based on name

I have a table TBL_TEST which has a column NAME with 5 rows, and those rows have the values 'Balkhab', 'Gosfandi', 'Sancharak', 'Aqcha'
I want to write a query with a WHERE clause that when the value in where class match with one of the values in NAME column in TBL_TEST then it should show only that value but when it does not match then it should show all the values in the table, below is select statement that is not working as expect.
SELECT NAME
FROM TBL_TEST
WHERE NAME = 'Balkhab' OR NAME != 'Balkhab'
I suspect you want something like this:
SELECT NAME
FROM TBL_TEST
WHERE NAME = 'Balkhab'
UNION ALL
SELECT NAME
FROM TBL_TEST
WHERE NOT EXISTS (SELECT 1 FROM TBL_TEST WHERE NAME = 'Balkhab');
IF Exists(select 'X' FROM TBL_TEST WHERE NAME = 'Balkhab')
SELECT NAME from TBL_TEST WHERE NAME = 'Balkhab'
ELSE
SELECT NAME FROM TBL_TEST
You can try this one below
select *
from table where not exists (select name from table where name = 'Aqcha') or
name ='Aqcha'
You can write a stored procedure for it with one parameter.
Create procedure(#Name varchar(max))
As
begin
If(Isnull(#name, 0))
Begin
If exists (select 1 from TBL_TEST xx where xx.name = #name)
Begin
Select *
From TBL_TEST
Where name = #name
End
Else
Begin
Select *
From TBL_TEST
End
End
Else
Begin
Select * from TBL_TEST
End
End
Pass your name as parameter to the stored procedure to get require result
stored procedure are the best option as you can avoid network traffic, less bandwidth as you can pass only require parameter and get required result

Querying different table based on a parameter

I have a stored procedure that I would like to query either the production or the "work in progress" table, based on the parameter I am passing in. I could write two separate stored procedures, but I thought this was worth a try.
something along the lines of:
create procedure getUserDetails
#userID int,
#prod varchar(5)
as
begin
select * from
if (#prod = 'true')
Begin
userprod_table
else
userwip_table
end
where something = 'something'
END
Is this at all possible? I wouldn't want to write 2 SP that are almost identical :-/
Why not use a simple if(#prod = 'true') statement like below:
if (#prod = 'true')
begin
select * from userprod_table where something = 'something'
end else
begin
select * from userwip_table where something = 'something'
end
You could use a CTE so that your main query isn't repeated
with usertable as
(
select * from userprod_table where 1 = #flag
union
select * from userwip_table where 0 = #flag
)
select ... from usertable ...

Use Select Statement as a Parameter Value

EXEC [dbo].[SP]
#Param = ( SELECT COUNT(id) FROM TABLE )
Gives errors, so what's the next best thing or what am I doing wrong?
Without using Declare Set etc. etc.
Set it before you run the stored proc?
SET #Para1 = (SELECT COUNT(id) FROM TABLE)
EXEC [dbo].[SP] #Param = #Para1

SQL Select Statement including SP Call has syntax error

MYTABLE has ID column. However, following query generates syntax error.
SELECT ID FROM MYTABLE
WHERE ID = EXEC MY_SP ID
What do you think is wrong here?
You can't call stored procedures inline like this.
A couple of options include:
1) Execute the stored procedure and store the results in a temp table. Then use that temp table.
e.g.
CREATE TABLE #Example
(
ID INTEGER
)
INSERT #Example
EXECUTE My_SP
SELECT t.ID FROM MyTable t JOIN #Example e ON t.ID = e.ID
DROP TABLE #Example
2) convert the sproc to a user defined function which you CAN call inline
e.g.
CREATE FUNCTION dbo.MyFunc()
RETURNS TABLE
AS
RETURN
(
SELECT ID FROM SomeTable WHERE ....
)
SELECT t.ID FROM MyTable t JOIN dbo.MyFunc() f ON t.ID = f.ID
3) If the sproc returns a single ID, consider returning an OUTPUT parameter from the sproc instead and use like this:
DECLARE #ID INTEGER
EXECUTE MY_SP #ID OUTPUT
SELECT ID FROM MYTABLE
WHERE ID = #ID
I don't think you need the exec statement, just call the sp, exec is expected to be a separate statement
I don't think you can do that at all. Are you perhaps thinking of a User Defined Function rather than a stored Procedure. Based on the context, you'll need a scalar UDF.
Try this:
SELECT ID FROM MYTABLE WHERE ID = ##SPID