Use Select Statement as a Parameter Value - sql

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

Related

How to add an update statement value to a variable?

I want to save data in a variable and use it later in a procedure.
UPDATE acc_Account
SET acc_Account.CompanyID = ( SELECT TOP 1
utl_Company.CompanyID
FROM utl_Company
ORDER BY CompanyID DESC
)
WHERE acc_Account.AccountNumber = #AccountNumber
how can I save the CompanyID in a variable to use it in an insert statement later on?
Have this in the beginning of your code:
declare #var varchar(20) -- change the data type according to your needs
set #var = (SELECT TOP 1 utl_Company.CompanyID FROM utl_Company ORDER BY CompanyID DESC)
Create a select local variable before the update statement, then set it, then use it.
DECLARE #companyID INT;
SELECT #companyID = "YOUR QUERY";
I think the efficient way would be using OUTPUT clause
DECLARE #TAB TABLE (CompanyID BIGINT )
UPDATE acc_Account
SET acc_Account.CompanyID = (
SELECT max(CompanyID) FROM utl_Company
)
output inserted.CompanyID into #TAB
WHERE acc_Account.AccountNumber = #AccountNumber
SELECT * FROM #TAB

HSQL SELECT Statement Not working

I am new in HSQL. Tried a Procedure like below;
CREATE PROCEDURE GetData(ObjectId VARCHAR(36)) READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN ATOMIC
DECLARE MaxVal NUMERIC(19,2);
DECLARE MinVal NUMERIC(19,2);
DECLARE BiggestObjectName VARCHAR(50);
DECLARE SmallestObjectName VARCHAR(50);
SET MaxVal = (SELECT MAX(HeightValue) FROM ObjectData WHERE ObjectId=ObjectId);
SET MinVal = (SELECT MIN(HeightValue) FROM ObjectData WHERE ObjectId=ObjectId);
SET BiggestObjectName = (SELECT ObjectName FROM ObjectData WHERE ObjectId=ObjectId AND HeightValue=MaxVal);
SET SmallestObjectName = (SELECT ObjectName FROM ObjectData WHERE ObjectId=ObjectId AND HeightValue=MinVal);
if MaxVal IS NOT NULL THEN
DECLARE result CURSOR WITH RETURN FOR
SELECT MaxVal AS MaximumHeight, MinVal AS MinimumHeight, BiggestObjectName AS LargestDisplayCaseName, SmallestObjectName AS SmallestDisplayCaseName FOR READ ONLY;
OPEN result;
END
But i get error;
Caused by: java.sql.SQLSyntaxErrorException: unexpected token: ; required: INTO
Is it not the correct syntax?
Any help is appreciated :)
There are several things wrong with your stored procedure. For one I don't think you can declare a cursor as part of an IF statement.
Assignment of a variable needs to be either using select ... into or you need to put the select statement between parentheses:
SET MaxVal = (SELECT MAX(HeightValue) FROM ObjectData WHERE ObjectId=ObjectId);
SET ObjectName = (SELECT ObjectName FROM ObjectData WHERE ObjectId=ObjectId AND HeightValue=MaxVal);
or
SELECT MAX(HeightValue)
into maxval
FROM ObjectData
WHERE ObjectId=ObjectId;
You also can't use = or <> to compare NULL values. if MaxVal != NULL THEN needs to be
if maxval is not null then
...
end if; --<< you also forgot the `end if`
You also can't use a SELECT statement without a FROM clause, and I don't think you can define a cursor that only selects values from variables in HSQLDB.
But don't need the intermediate selects anyway, you can do that in a single select:
CREATE PROCEDURE GetData(ObjectId VARCHAR(36)) READS SQL DATA
DYNAMIC RESULT SETS 1
BEGIN ATOMIC
DECLARE result CURSOR FOR
select o1.heightvalue as maximumheight, o1.objectname as displaycasename
from objectdata o1
where objectid = 'one'
and heightvalue = (select max(heightvalue)
from objectdata o2
where o2.objectid = o1.objectid);
OPEN result;
END;
You are not using the correct syntax to create the procedure. According to the syntax you have to put the value(s) selected from table into a local variable(s). Follow the following example.
CREATE PROCEDURE get_customer(IN id INT, OUT firstname VARCHAR(50), OUT lastname VARCHAR(50))
READS SQL DATA
BEGIN ATOMIC
-- this statement uses the id to get firstname and lastname
SELECT first_name, last_name INTO firstname, lastname FROM customers WHERE cust_id = id;
END
I hope it'll help you.

dynamic sql count in a variable

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.

Add filtering on top of Stored Procedure

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)

How to execute a Stored Procedure on the results of a SQL Server CTE

I have a CTE which returns DISTINCT ID's. I want to execute a scalar function on each of the Id's returned.
WITH cte (reqID) as
(SELECT DISTINCT pol.ReqID FROM
LOG_PackingListItems pli
JOIN
v_PO_LN pol on pol.PO_ID = pli.PoId
WHERE
pli.PackingListHeaderID = 1)
EXEC dbo.spUpdateLOG_ReqCompleteCheck reqID -- Error "Incorrect Syntax near EXEC"
The EXEC line is what I want to make work but I get a syntax error. Not sure if what I want to do is possible or if I do in fact have a syntax error. Any ideas?
EDIT:
I'm adding the code for the Stored Procedure since I am now using a Table-Valued Parameter as suggested by realnumber3012
EDIT:
I have changed my CTE code so it populates a Table-Type as realnumber has suggested. I now get an error when executing spUpdateLOG_ReqCompleteCheck "Subquery returns more than one value."
DECLARE #ReqIdTVP as ReqIdType;
DELETE FROM #ReqIDTVP;
with cte (reqID) as
(select distinct pol.ReqID from
LOG_PackingListItems pli
join
v_PO_LN pol on pol.PO_ID = pli.PoId
where
pli.PackingListHeaderID = #PackingListHeaderID)
INSERT INTO #ReqIdTVP
SELECT * FROM cte
EXEC dbo.spUpdateLOG_ReqCompleteCheck #ReqIdTVP
Sproc code :
Alter PROCEDURE spUpdateLOG_ReqCompleteCheck
(#ReqIdTVP ReqIdType READONLY )
AS
BEGIN
DECLARE #TotalOrd int
DECLARE #TotalRx int
DECLARE #ReqID char(8)
SET #ReqID = (SELECT ReqID FROM #ReqIdTVP)
SET #TotalOrd = (SELECT ISNULL(SUM(ORD_QTY),0)
FROM dbo.v_PoLnNonFreight l
WHERE l.ReqID = #reqID)
SET #TotalRx = (SELECT ISNULL(SUM(TotalRxSite),0)
FROM dbo.v_PoLnNonFreight l
WHERE l.ReqID = #reqID)
IF #TotalRx >= #TotalOrd
BEGIN
DECLARE #curDate datetime
SET #CurDate = ISNULL(#CurDate,GetDate())
SET NOCOUNT ON;
UPDATE LOG_ReqHeader
SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
WHERE ReqID = #ReqID
END
END
Seems that the only thing your stored proc does is to update a logging table: (it only changes state via this statement and doesn't return anything????
UPDATE LOG_ReqHeader
SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
WHERE ReqID = #ReqID
How about splitting the logic out and write a function (inline if possible that will evaluate the condition you are looking for (didn't really understand what you are doind there) -- run the function on the results of the CTE (wrapping it in another CTE if you want) with the CROSS APPLY OPERATOR.
You'd end up with a result set that looks like [ReqId], [UpdateLog] (where updateLog is a BIT)
Then simply do a set based upadete JOINING to the results:
UPDATE l SET
ReqCompleteDate = #curDate,
ReqStatus = 'Complete'
FROM
LOG_ReqHeader AS l
JOIN <CTE> AS c ON c.[ReqID] = l.[ReqID]
WHERE
c.[UpdateLog] = 0x1
Does this make any sense?