SQL Stored Procedure set variables using SELECT - sql-server-2005

I have a stored procedure in SQL Server 2005 with multiple variables and I want to set the values of these variables using a select statement. All three variables come from a same table and there should be a way to set them using one select statement instead of the way I currently have as shown below. Please help me to figure it out.
DECLARE #currentTerm nvarchar(max)
DECLARE #termID int
DECLARE #endDate datetime
SET #currentTerm =
(
Select CurrentTerm from table1 where IsCurrent = 1
)
SET #termID =
(
Select TermID from table1 where IsCurrent = 1
)
SET #endDate =
(
Select EndDate from table1 where IsCurrent = 1
)

select #currentTerm = CurrentTerm, #termID = TermID, #endDate = EndDate
from table1
where IsCurrent = 1

One advantage your current approach does have is that it will raise an error if multiple rows are returned by the predicate. To reproduce that you can use.
SELECT #currentTerm = currentterm,
#termID = termid,
#endDate = enddate
FROM table1
WHERE iscurrent = 1
IF( ##ROWCOUNT <> 1 )
BEGIN
RAISERROR ('Unexpected number of matching rows',
16,
1)
RETURN
END

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

Are these SQL queries equivalent?

I'm quite new to SQL. The first query is "correct" but I want to rewrite it so that it returns nothing instead of "Ok". Query #2 is my try. According to me, it is correct because the JOIN condition separates all rows where the two dates are different. But I'm not sure at this and as I said I'm kind a new to this.. The problem is that I have no test-data right to cross verify. Could you please help?
1
DECLARE #date1 datetime,
#date2 datetime
SELECT #date1 = Max(date) FROM table1
WHERE 1 = 1
AND id = 1
AND id2 = 11
SELECT #date2 = Max(date) FROM table2
WHERE 1 = 1
AND id = 2
AND id2 = 11
SELECT
CASE
WHEN COALESCE(#date1,0) = #date2
THEN 'Ok'
WHEN CONVERT(TIME,GETDATE()) < '19:00:00'
THEN 'Ok'
ELSE 'Not Ok'
END AS Warning
2:
DECLARE #date1 datetime
,#date2 datetime
,#id int = 1
SELECT #date1 = COALESCE(MAX(date),0) FROM table1
WHERE 1 = 1
AND id = #id
AND id3 = 11
SELECT #date2= MAX(date) FROM table1
WHERE 1 = 1
AND id = #id
AND id2 = 11
SELECT
'Warning' = CASE WHEN CONVERT(TIME,GETDATE()) > '19:00:00'
THEN 'not ok'
END
FROM dbo.table1 AS a
INNER JOIN dbo.table AS a2 ON 1 = 1
AND #date1 != #date2
WHERE 1 = 1
AND a.nBranchId = #id
AND a.nInstrId = 11
Not nearly equivalent. In both versions, the #date1 variable will be NULL if there are no rows satisfying the conditions of the query used to initialise its value.
If that's the case, the last select from version 1 will return a single row with value being either "Ok" or "Forwardpoints missing in XP_ResultsOutRightForwards", depending on the current time.
The version 2, however, will not return any rows whatsoever because you used this variable in the condition of an inner join. The inequality does not work with NULL values, so you will receive an empty set.

Can Someone look at my Stored Procedure and tell me where i am going wrong?

I'm writing an app and I'm generating a random order number in C# and before I do an insert statement I need to verify that there is no duplicate order number. This is my stored procedure (it's just a test procedure to help in figuring this out)
CREATE PROCEDURE Test$For$Dupes
(#RandNum int)
AS
declare #myNum int
SELECT OrderNumber, COUNT(*)
FROM [TEST]
WHERE OrderNumber = #RandNum
IF(COUNT(*) < 1)
SET #myNum = 0
IF(COUNT(*) > 1)
SET #myNum = 1
What I am trying to accomplish is if there is a duplicate I need to output a 1 and let my c# code regenerate a random number, and if there is no duplicate then I need an output of 0 so I can continue on my insert into my table.
I had this figured out a few years ago and can't find my code with how I did it, and now I am lost trying to figure this out. Any ideas?
It's not working just yet, I'm getting this error:
Msg 8120, Level 16, State 1, Procedure Test$For$Dupes, Line 8
Column 'TEST.OrderNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
This is a little more efficient because it stops looking thru the table when it finds a match. And I think it is clearer.
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
BEGIN
IF EXISTS (SELECT 1 FROM [TEST] WHERE OrderNumber = #RandNum)
SELECT 1
ELSE
SELECT 0
END
You would read this on the C# side like:
using (SqlConnection cnn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = cnn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Test$For$Dupes";
cmd.Parameters.AddWithValue("#RandNum", 100);
return (int) cmd.ExecuteScalar()
}
You don't even need the if..else condition, you can just use the following code:
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
BEGIN
declare #myNum int
SELECT #myNum = CASE COUNT(*)
WHEN 0 THEN 0
ELSE 1
END
FROM test
WHERE orderNumber = #RandNum
GROUP BY orderNumber
END
fiddle:http://sqlfiddle.com/#!3/51a0e/22
In your code, you are trying to compare in if condition as Count(*) which is not a variable..
you need to declare a variable and set that variable in the query then compare that variable in an if condition. So if i rectify your code it will be:
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
Begin
declare #myNum int
declare #orderNoCount int
select #orderNoCount=COUNT(*) FROM [TEST]
WHERE OrderNumber = #RandNum
IF(#orderNoCount =< 1)
Set #myNum = 0
IF(#orderNoCount > 1)
SET #myNum = 1
END
in your code you are missing condition when ordernumber = 1... So I have added that condition too.
You can try this also:
CREATE PROCEDURE Test$For$Dupes
(
#RandNum int
)
AS
BEGIN
IF (select Count(Distinct OrderNumber) FROM [TEST] WHERE OrderNumber = #RandNum) >= 1
Set #myNum = 1
ELSE
SET #myNum = 0
END

IF ELSE condition in SQL select

I want to do a if-else condition statement in SQL Server but am not sure how.
Inside the stored procedure I have the following parameters:
#MarketId nvarchar (10),
#RegionId nvarchar (10)
And the following statement:
select * from Interaction I
where
(#MarketId = 0 ) OR (I.MarketId = (SELECT Id FROM Market WHERE ExternalId = #MarketId))
What I want to do is to check the value of #MarketId
if #MarketId = 0
then I want the where condition for I.MarketId to get its Ids from elsewhere like
(SELECT ID FROM Market WHERE ExternalId = #RegionId)
otherwise, if its 1, then I just want to leave it as is and get the Id from #MarketId instead of #RegionId..
How should I go about this?
Thanks!
This should work:
SELECT *
FROM Interaction I
WHERE ( #MarketID = 0
AND EXISTS (SELECT 1 FROM Market
WHERE ExternalId = #RegionId AND Id = I.MarketID)
OR I.MarketID = #MarketID

Update field by a function

I have the function which gets ID and returns date from table if it exists or returns current date if isn't:
CREATE FUNCTION [dbo].[CLOSEDATE] (#ID int)
RETURNS datetime
AS
BEGIN
DECLARE #closed int;
DECLARE #result datetime;
SELECT #result = created_on from dbo.statuses_history
WHERE journalized_id = #ID and new_status = 'Закрыто';
IF #result IS NULL
SELECT #result = GETDATE()
RETURN (DATEADD(dd, 0, DATEDIFF(dd, 0, #result)))
END;
The next queries return correct date from table:
select dbo.closedate(4170)
select dbo.closedate(id) from issues where id = 4170
And the next code update the record correctly (values from table):
DECLARE #d AS datetime
select #d = dbo.closedate(4170)
UPDATE issues SET created_on = #d WHERE issues.id = 4170
But I get current date in the field if I update the record:
UPDATE issues
SET created_on = dbo.CloseDate(id)
WHERE issues.id = 4170
It looks like the ID parameter doesn't pass to the function.
Your tests (that I missed on the first reading, sorry) are enough to make me very confused. It seems that your test results should not be possible.
My only suggestion would be to recode the function and see what happens...
CREATE FUNCTION [dbo].[CLOSEDATE] (#ID int)
RETURNS TABLE
AS
RETURN
SELECT
(DATEADD(dd, 0, DATEDIFF(dd, 0, ISNULL(MAX(created_on), GetDate())))) AS close_date
FROM
dbo.statuses_history
WHERE
journalized_id = #ID
AND new_status = 'Закрыто'
And then...
UPDATE
issues
SET
created_on = fn.close_date
FROM
issues
CROSS APPLY
dbo.CLOSEDATE(id) AS fn
WHERE
issues.id = 4170
Cross Apply is what you looking for I think.