sql loop update with multiple rows returned - sql

I've got to update a column value by decreasing the value in the column by a variable.
There are two conditions:
1. where the row count = 1
2. where the row count is more than 1
I've got it set to do the single row count but need help when the query returns multiple rows.
set #rowsCounted = (select COUNT(QuantityA) from Offers where WID = #wId and ND = #nd)
if(#rowsCounted = 1)
begin
set #QuantityAvailable = (select QuantityA from Offers where WID = #wId and ND = #nd)
set #QuantityAvailable = (select #QuantityAvailable - #QuantityAdjusted)
update Offers
set QuantityA = #QuantityAvailable
where WID = #wId and ND = #nd
end
else
begin
select #rowsCounted as rowsCounted -- example of 4 rows with values of = 287,280,288,288
--begin loop as the QuantityA may contain different values
end

If #QuantityAdjusted is constant for the procedure, then you only need one update statement. Use set-based thought constructs rather than procedural-based ones:
update Offers
set QuantityA = QuantityA - #QuantityAdjusted
where WID = #wId and ND = #nd
This will update in a set-based operation, and there is no need to construct your own loop. This is part of what SQL engines are meant to do.

Related

SQL, How to take into account previously populated records when populating a sequential number ID for a field in a nightly script

I am trying to include a clause in a script that runs nightly that will populate a three digit number into a field if that record meets a set of conditions. I will include the script that I have written for this below but I do not know how to account for the numbers that will have been populated on previous nights and keep the new numbers to be populated in sequential order. The numbers must start at 100 and go up by 1 each time a new record is found that meets the conditions.
All help is appreciated.
My current script:
DECLARE #myVar NVarchar(50)
SET #myVar = 99
UPDATE Database1..Thing
SET #myVar = Thing_Number_NEW = #myVar + 1
WHERE (Thing_Number = '' OR Thing_Number IS NULL)
AND Thing_Number_Needed = 'Yes'
AND Symbology IN (2, 3, 55, 66)
AND Thing_Number_New IS NULL
AND Last_edited_user is not null
Is this what you want?
UPDATE Database1..Thing
SET Thing_Number_NEW = COALESCE(n.max_Thing_Number_NEW + 1, 100)
FROM (SELECT MAX(Thing_Number_NEW) as max_Thing_Number_NEW FROM Database1..Thing) n
WHERE (Thing_Number = '' OR Thing_Number IS NULL)
Thing_Number_Needed = 'Yes' AND
Symbology IN (2, 3, 55, 66) AND
Thing_Number_New IS NULL AND
Last_edited_user is not null;

SQL : Update value when the value in the database is null

I know this is already asked question and possible to be close.
But i really want a answer, I already searched through the internet, Read documentations, Blogs, and Question to SO.
This is my Query so Far,
declare #count numeric
select #count = (select count(1) from E496_TitleReference a where
exists (select 1 from #tempTransactions b where a.EPEB_RoD = b.tEPEB_RoD and
a.EPEB_ENO = b.tEPEB_ENO and a.EPEB_ID = b.tEPEB_ID and a.Title_Seq = b.tTitle_Seq))
update E496_TitleReference
set PrintStatus = '{0}',Is_AESM=isnull(-1,Is_AESM)
from E496_TitleReference a where
exists (select 1 from #tempTransactions b where a.EPEB_RoD = b.tEPEB_RoD and
a.EPEB_ENO = b.tEPEB_ENO and a.EPEB_ID = b.tEPEB_ID and a.Title_Seq = b.tTitle_Seq)
if ##rowcount <> #count
begin
rollback tran
Print "Error: There is an error on table E496_TitleReference."
return
end
go
For eg, In my table in Database i have column name Is_AESM, In Is_AESM column it have 4 values.
Is_AESM
NULL
NULL
-1
-2
Something like this.
Now when i run my script, it has no problem when i run it,
Is_AESM=isnull(-1,Is_AESM)
In this query it will detect if Is_AESM is null, it will update Is_AESM = -1 if not it will retain the value.
Now my problem is, if my query detect Is_AESM has a null value, it will update all the value to -1.
Is_AESM
-1
-1
-1
-1
The result is something like that. Now i want is update only the null value not all the value in column Is_AESM.
I think this query is wrong Is_AESM=isnull(-1,Is_AESM).
Any ideas will be a big help.
You may try with coalsece() function
update E496_TitleReference
set PrintStatus = '{0}',Is_AESM=coalsece(Is_AESM,-1)
from E496_TitleReference a where
exists (select 1 from #tempTransactions b where a.EPEB_RoD = b.tEPEB_RoD and
a.EPEB_ENO = b.tEPEB_ENO and a.EPEB_ID = b.tEPEB_ID and a.Title_Seq = b.tTitle_Seq)
you need to replace order of parameters.
Is_AESM=isnull(Is_AESM, -1)
You can use COALSECE function. It returns the first non-null entry from the given list. So:
Is_AESM= COALSECE(IS_AESM,-1)
This will return IS_AESM value if it is not null (since it is the first non-null value)
Else if IS_AESM is NULL then it returns -1 (since it is the non-null value)

Most effifient way to update one column from 3 columns

Is this the most efficient way to update one single column from three different columns?
UPDATE TBL_FR2052A_TPOS_HIST_SPLIT
SET REPORTABLE_AMOUNT = ISNULL(PRINCIPAL,0)
UPDATE TBL_FR2052A_TPOS_HIST_SPLIT
SET REPORTABLE_AMOUNT = ISNULL(INTEREST,0)
UPDATE TBL_FR2052A_TPOS_HIST_SPLIT
SET REPORTABLE_AMOUNT = ISNULL(RAW_DATA_AMOUNT,0)
I am using SQL Server. Thanks!
Looks like COALESCE() would help
UPDATE TBL_FR2052A_TPOS_HIST_SPLIT
SET REPORTABLE_AMOUNT = COALESCE(ROW_DATA_AMOUNT, INTEREST, PRINCIPAL, 0)
REPORTABLE_AMOUNT will then be updated with the first value in the COALESCE() that is not null.
Please try SQL : Case - When - End if you are checking Null for update fields.
Egs:
UPDATE TBL_FR2052A_TPOS_HIST_SPLIT
SET REPORTABLE_AMOUNT =
case when ISNULL(PRINCIPAL,0) <> 0 then PRINCIPAL
case when ISNULL(INTEREST,0) <> 0 then INTEREST
case when ISNULL(RAW_DATA_AMOUNT,0) <> then RAW_DATA_AMOUNT
else 0 --default value
End
Regards
Abdul

conditional handling of update sql script depending on input parameter

I am new to SQL and using Oracle 11. I need to write a sql script which uses different update command based on whether the input param is null or not null.
I need something like this
['&' followed by the parameter name is the way i see parameters being used in other such
script for our project]
IF &PRG_ID IS NULL
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID);
ELSE
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE
P.PROGRAM_ID = &PRG_ID AND EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID);
END IF;
Something like (is not tested):
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID)
AND (&PRG_ID IS NULL OR P.PROGRAM_ID = &PRG_ID);
But take into account this change may lead to the performance degradation for the case when PRG_ID has definite value.

Stored procedure to find next and previous row in SQL Server 2005

Right now I have this code to find next and previous rows using SQL Server 2005. intID is the gallery id number using bigint data type:
SQL = "SELECT TOP 1 max(p.galleryID) as previousrec, min(n.galleryID) AS nextrec FROM gallery AS p CROSS JOIN gallery AS n where p.galleryid < '"&intID&"' and n.galleryid > '"&intID&"'"
Set rsRec = Server.CreateObject("ADODB.Recordset")
rsRec.Open sql, Conn
strNext = rsRec("nextrec")
strPrevious = rsRec("previousrec")
rsRec.close
set rsRec = nothing
Problem Number 1:
The newest row will return nulls on the 'next record' because there is none. The oldest row will return nulls because there isn't a 'previous record'. So if either the 'next record' or 'previous record' doesn't exist then it returns nulls for both.
Problem Number 2:
I want to create a stored procedure to call from the DB so intid can just be passed to it
TIA
This will yield NULL for previous on the first row, and NULL for next on the last row. Though your ordering seems backwards to me; why is "next" lower than "previous"?
CREATE PROCEDURE dbo.GetGalleryBookends
#GalleryID INT
AS
BEGIN
SET NOCOUNT ON;
;WITH n AS
(
SELECT galleryID, rn = ROW_NUMBER()
OVER (ORDER BY galleryID)
FROM dbo.gallery
)
SELECT
previousrec = MAX(nA.galleryID),
nextrec = MIN(nB.galleryID)
FROM n
LEFT OUTER JOIN n AS nA
ON nA.rn = n.rn - 1
LEFT OUTER JOIN n AS nB
ON nB.rn = n.rn + 1
WHERE n.galleryID = #galleryID;
END
GO
Also, it doesn't make sense to want an empty string instead of NULL. Your ASP code can deal with NULL values just fine, otherwise you'd have to convert the resulting integers to strings every time. If you really want this you can say:
previousrec = COALESCE(CONVERT(VARCHAR(12), MIN(nA.galleryID)), ''),
nextrec = COALESCE(CONVERT(VARCHAR(12), MAX(nB.galleryID)), '')
But this will no longer work well when you move from ASP to ASP.NET because types are much more explicit. Much better to just have the application code be able to deal with, instead of being afraid of, NULL values.
This seems like a lot of work to get the previous and next ID, without retrieving any information about the current ID. Are you implementing paging? If so I highly recommend reviewing this article and this follow-up conversation.
Try this (nb not tested)
SELECT TOP 1 max(p.galleryID) as previousrec, min(n.galleryID) AS nextrec
FROM gallery AS p
CROSS JOIN gallery AS n
where (p.galleryid < #intID or p.galleryid is null)
and (n.galleryid > #intID or n.galleryid is null)
I'm assuming you validate that intID is an integer before using this code.
As for a stored procedure -- are you asking how to write a stored procedure? If so there are many tutorials which are quite good on the web.
Since Hogan contributed with the SQL statement, let me contribute with the stored proc part:
CREATE PROCEDURE spGetNextAndPreviousRecords
-- Add the parameters for the stored procedure here
#intID int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT TOP 1 max(p.galleryID) as previousrec, min(n.galleryID) AS nextrec
FROM gallery AS p
CROSS JOIN gallery AS n
where (p.galleryid < #intID or p.galleryid is null)
and (n.galleryid > #intID or n.galleryid is null)
END
And you call this from code as follows (assuming VB.NET):
Using c As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString)
c.Open()
Dim command = New SqlCommand("spGetNextAndPreviousRecords")
command.Parameters.AddWithValue("#intID", yourID)
Dim reader as SqlDataReader = command.ExecuteReader()
While(reader.Read())
' read the result here
End While
End Using