I am trying to execute this query with some 'conditional logic', it is my first attempt doing something like this in databases.
Here is the code:
DECLARE #iddevice INT;
SET #iddevice = 15;
IF(#iddevice = 15 AND DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'PortA')
BEGIN
UPDATE DEVICEATTRIBUTES
SET VALUE = '4701'
WHERE IDDEVICE = 15 AND DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'PortA'
END
IF(#iddevice = 15 AND DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'PortB')
BEGIN
UPDATE DEVICEATTRIBUTES
SET VALUE = '4711'
WHERE IDDEVICE = 15 AND DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'PortB'
END
IF(#iddevice = 15 AND DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'IP')
BEGIN
UPDATE DEVICEATTRIBUTES
SET VALUE = '172.19.106.201'
WHERE IDDEVICE = 15 AND DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'IP'
END;
GO
I am aware that something with the syntax is wrong, my question is ... how can I add DEVICEATTRIBUTES.DEVICEATTRIBUTE inside the 'if' clause?
You script you can re-write as follow:
DECLARE #iddevice INT;
SET #iddevice = 15;
UPDATE DEVICEATTRIBUTES
SET VALUE =
CASE
WHEN DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'PortA' THEN '4701'
WHEN DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'PortB' THEN '4711'
WHEN DEVICEATTRIBUTES.DEVICEATTRIBUTE = 'IP' THEN '172.19.106.201'
END
WHERE IDDEVICE = #iddevice AND DEVICEATTRIBUTES.DEVICEATTRIBUTE IN ('PortA', 'PortB', 'IP')
In SQL Server, you can use UPDATE with JOIN:
UPDATE DA
SET VALUE = '4701'
FROM DEVICEATTRIBUTES DA JOIN
(VALUES ('PortA', '4701'),
('PortB', '4711'),
('IP', '172.19.106.201')
) V(DEVICEATTRIBUTE, VALUE)
ON DA.DEVICEATTRIBUTE = V.DEVICEATTRIBUTE
WHERE IDDEVICE = 15;
The VALUES clause is a handy way to add in the values you want to change -- and it reduces the risk of typos.
However, in your code, you can just use three UPDATEs. The IF statements are not necessary. If no rows match the WHERE clause then no rows are updated.
Related
I want to update FirstTable from SecondTable, but there are many complications.
This is the main query:
UPDATE x.FirstTable Table1
set Table1.UpdatedColumn = (
SELECT Table2.V_PROD_CODE
FROM y.SecondTable Table2
WHERE Table2.XX_V_ACCOUNT_ID1 = Table1.XX_V_ACCOUNT_ID1
AND Table2.XX_V_ACCOUNT_ID2 = Table1.XX_V_ACCOUNT_ID2
AND Table2.XX_V_ACCOUNT_ID3 = Table1.XX_V_ACCOUNT_ID3
AND Table2.c_Date between '17-Apr-2018' and '27-Apr-2018'
AND Table2.c_DATE = Table1.c_date)
WHERE Table1.c_date between '17-Apr-2018' and '27-Apr-2018'
AND length(Table1.xx_v_account_id1) = 12;
It is taking too long, so I thought about creating a cursor:
create or replace procedure wco as
cursor UpdateCursor is
SELECT Table2.V_PROD_CODE
FROM y.SecondTable Table2
INNER JOIN x.FirstTable Table1 on SUBSTR(Table1.V_CAST_REF_CODE, 6, 8) = SUBSTR(Table2.V_CAST_REF_CODE, 6, 8)
WHERE Table2.XX_PRODUCT_CODECCOUNT_ID1 = Table1.XX_PRODUCT_CODECCOUNT_ID1
AND Table2.XX_PRODUCT_CODECCOUNT_ID2 = Table1.XX_PRODUCT_CODECCOUNT_ID2
AND Table2.XX_PRODUCT_CODECCOUNT_ID3 = Table1.XX_PRODUCT_CODECCOUNT_ID3
AND Table2.fic_mis_date between '17-Apr-2018' and '27-Apr-2018'
AND Table2.c_DATE = Table1.c_date
for update;
v_PRODUCT_CODE Table2.V_PROD_CODE%type;
begin
open UpdateCursor;
loop
fetch UpdateCursor into v_PRODUCT_CODE;
exit when UpdateCursor%notfound;
update XXBADWH.xxba_dwh_instrument_master INST
set INST.v_product_code = v_PRODUCT_CODE
WHERE current of UpdateCursor
AND INST.fic_mis_date between '17-Apr-2018' and '27-Apr-2018'
AND length (INST.xx_v_account_id1) = 12;
end loop;
close UpdateCursor;
end;
exec wco;
drop procedure wco;
What is wrong with the query? and any better practices?
For this query:
UPDATE x.FirstTable Table1
SET Table1.UpdatedColumn = (
SELECT Table2.V_PROD_CODE
FROM y.SecondTable Table2
WHERE Table2.XX_V_ACCOUNT_ID1 = Table1.XX_V_ACCOUNT_ID1 AND
Table2.XX_V_ACCOUNT_ID2 = Table1.XX_V_ACCOUNT_ID2 AND
Table2.XX_V_ACCOUNT_ID3 = Table1.XX_V_ACCOUNT_ID3 AND
Table2.c_Date between DATE '2018-04-17' and DATE '2018-04-27' AND
Table2.c_DATE = Table1.c_date
)
WHERE Table1.c_date between DATE '2018-04-17' and DATE '2018-04-27' AND
length(Table1.xx_v_account_id1) = 12;
You want indexes on Table1(length(xx_v_account_id1), c_date) and Table2(XX_V_ACCOUNT_ID1, XX_V_ACCOUNT_ID2, XX_V_ACCOUNT_ID3, c_DATE).
I would start with the indexes (tested on a select select statement). Cursors are rarely the route to better performance.
I need to optimize the Procedure below. Syntax should be in Informix.
Here a table update is required with sequential update. It seems to be very large.Can it be optimized.
CREATE OR REPLACE PROCEDURE ENTRY() LANGUAGE SQL
BEGIN ATOMIC
DECLARE record integer;
DECLARE txaa_id bigint;
DECLARE id bigint;
DECLARE createDatetimed timestamp;
DECLARE idPlus bigint;
set record = 0;--
set txaa_id = 0;--
set id = 0;--
set idPlus = 0;--
set createDatetimed = null;--
FOR v_row1 as select distinct txaa_id from finalBaseData
DO
FOR v_row2 as select txsa_id , finalBaseData.txaa_id , finalBaseData.createdatetime from tx_status_audit,finalBaseData where tx_status_audit.txaa_id = v_row1.txaa_id and tx_status_audit.txaa_id = finalBaseData.txaa_id and tx_status_audit.cdts = 'OUT' order by tx_status_audit.create_datetime desc fetch first 1 rows only
DO
set record = record + 1;
IF ( record = 1)
THEN
set id = v_row2.txsa_id;
set idPlus = id + 1;
set txaa_id = v_row2.txaa_id;
set createDatetimed = v_row2.createdatetime;
END IF;
END FOR;
insert into tx_status_audit values (idPlus,'CMPT',txaa_id,'HWNG',createDatetimed);
set record = 0;
set idPlus = 0;
set txaa_id = 0;
set createDatetimed = null;
END FOR;
END;
I have a VB.NET application that is creating some INSERT, UPDATE, DELETE statements based on the users selections. I can tell that the SQL is being successfully executed on SQL Server 2008 (I see the table records adjusting appropriately), except one of my insert triggers is not firing.
SQL generated by the application code:
insert into [RECLASS_BALANCE_ADJSTMNT]( PRGRM_REC_ID, DEDUCTN_REC_ID, RBA_YR_PD_NUM, RBA_AMOUNT, RBA_TYPE, ADJUSTER_USER_ID )
values (5504, 8154, dbo.getCurrentYrPdNum(), abs(-21510.70), 'M', '10139638');
insert into [MATCH] (DEDUCTN_REC_ID, PRGRM_REC_ID, YR_PD_NUM, MATCH_TYPE_FLG)
values (8154, 5504, dbo.getCurrentYrPdNum(), 'M');
delete from [POTENTIAL_MATCH]
where deductn_rec_id = 8154
and prgrm_rec_id = 5504;
update [PROGRAM_GL_DTL]
set MATCH_FLG = 'Y', MATCH_FLG_MODIFIED_TIMESTAMP = getdate()
where PRGRM_REC_ID = 5504;
update [DEDUCTION]
set MATCH_FLG = MATCH_FLG + 1
where DEDUCTN_REC_ID = 8154;
INSERT trigger:
CREATE TRIGGER [dbo].[check_partial_offset_status]
ON [dbo].[RECLASS_BALANCE_ADJSTMNT]
FOR INSERT
AS
BEGIN
DECLARE #deductnRecId int;
DECLARE #deductnBalance decimal(18,2);
DECLARE #deductnOriginalAmount decimal(18,2);
SELECT #deductnRecId = i.deductn_rec_id FROM inserted i;
SELECT #deductnBalance = ds.ytd_amt, #deductnOriginalAmount = ds.original_invoice_amount
FROM deduction_summary_updt ds
WHERE ds.deductn_rec_id = #deductnRecId;
IF ABS(#deductnBalance) > 0
BEGIN
UPDATE deduction
SET comment_id = 12
WHERE deductn_rec_id = #deductnRecId;
END --partial matched
IF #deductnBalance = #deductnOriginalAmount
BEGIN
UPDATE deduction
SET comment_id = 6
WHERE deductn_rec_id = #deductnRecId;
END --unmatched
IF #deductnBalance = 0
BEGIN
UPDATE deduction
SET comment_id = 9
WHERE deductn_rec_id = #deductnRecId;
END --fully matched
DECLARE #prgrmRecId int;
DECLARE #prgrmBalance decimal(18,2);
DECLARE #prgrmOriginalAmount decimal(18,2);
SELECT #prgrmRecId = i.prgrm_rec_id FROM inserted i;
SELECT #prgrmBalance = rs.ytd_amt, #prgrmOriginalAmount = rs.reclass_amount
FROM reclass_summary rs
WHERE rs.prgrm_rec_id = #prgrmRecId;
IF ABS(#prgrmBalance) > 0
BEGIN
UPDATE program_gl_dtl
SET comment_id = 12
WHERE prgrm_rec_id = #prgrmRecId;
END --partial matched
IF #prgrmBalance = #prgrmOriginalAmount
BEGIN
UPDATE program_gl_dtl
SET comment_id = 5
WHERE prgrm_rec_id = #prgrmRecId;
END --unmatched
IF #prgrmBalance = 0
BEGIN
UPDATE program_gl_dtl
SET comment_id = 10
WHERE prgrm_rec_id = #prgrmRecId;
END --fully matched
END
GO
I'm trying to understand why the "INSERT INTO [RECLASS_BALANCE_ADJSTMNT].." generated by the application code does not cause the trigger to fire.
I appreciate any help. Thanks!
I'm writing a stored procedure and it's working for if but not for else. For if I'm getting the correct ID value but for else it's just giving me null.
SELECT #ID = ID FROM PRODUCTS WHERE SN = #SN
SELECT #Chip_ID = Chip_ID FROM PRODUCTS WHERE SN = #SN
SELECT #Power = Power From Module_Cycle WHERE ChipID = #Chip_ID
SELECT #Test_ID=Test_ID FROM TestEE_Mod WHERE ID=#ID AND #TypeID = TypeID
IF(#Test_ID IS NOT NULL)
BEGIN
IF(#TypeID = '3')
BEGIN
SELECT #Temp_TestID=TestID FROM TempCycle WHERE ChipID = #Chip_ID AND #Power = 'false'
BEGIN
UPDATE TestEE_Mod SET Temp_TestID = #Temp_TestID WHERE ID = #ID AND TypeID = #TypeID
END
END
ELSE
BEGIN
SELECT #Temp_TestID=TestID FROM TempCycle WHERE ChipID = #Chip_ID AND #Power = 'true'
BEGIN
UPDATE TestEE_Mod SET Temp_TestID = #Temp_TestID WHERE ID = #ID AND TypeID = #TypeID
END
END
END
Most likely the issue lies in the #Power variable. In your two SELECT statements, the only difference is that one includes #Power = 'false' in the WHERE clause, while the other includes #Power = 'true'.
Since #Power is a variable, not an actual column in your TempCycle table, I'm guessing you actually meant to filter by Power = #Power in both of them.
IF( #ActiveStatus = 1 )
BEGIN
#PasswordStatus = 3
END
ELSE
SET #PasswordStatus = (SELECT password_status
FROM tbl_user
WHERE login_name = #LoginName_fromApp
AND password=#Pass
)
I am using Microsoft SQL Server Management Studio..
yes
In IF clause you need to set variable so use select or set, do not write directly #PasswordStatus = 3 write set/select #PasswordStatus = 3
try
if( #ActiveStatus = 1 )
begin
--chage of code
set #PasswordStatus = 3 --or select #PasswordStatus = 3
END
else
begin
Set #PasswordStatus = (select password_status from tbl_user where login_name=#LoginName_fromApp and password=#Pass)
end
EDIT
Comment of -# marc_s Use SET #Var = 3 if you're just setting a "scalar" value - use SELECT #Var = ID FROM dbo.Table1 if you're actually selecting from a table (or view)
when you r setting valuer to any variable use Set as followed
if( #ActiveStatus = 1 )
begin
Set #PasswordStatus = 3
END
else
begin
Set #PasswordStatus = (select password_status from tbl_user where
login_name=#LoginName_fromApp and password=#Pass)
end
Select #PasswordStatus
Another one
select
#PasswordStatus = case when #ActiveStatus = 1 then 3 else password_status end
from
tbl_user
where
login_name = #LoginName_fromApp and password=#Pass