I'm kinda new at pl/sql developing, and I have this trigger created:
create or replace trigger schema.trg_CP
after insert on tdlrp
referencing old as old
for each row
---------------------------------------------------------------------------------------------------------
declare
v_fkidnc schema.tdlrp.fkidnc%type;
v_errortype schema.tdlrp.xerrort%type;
v_fkerrorID schema.tepm.ferror%type;
v_linerror number;
v_pr schema.tpm.pipm%type;
v_pkdocid_r schema.tddr.pidr%type;
---------------------------------------------------------------------------------------------------------
begin
if inserting then
select fkidnc, xerrort
into v_fkidnc, v_errortype
from schema.tdlrp;
--
if v_fkidnc = 1 then
if v_errortype = 1 then
select ferror, fipcm
into v_fkerrorID, v_linerror
from schema.tepm;
select pipm
into v_pr
from schema.tpm
where fipcm = v_linerror;
insert into schema.tddr(pidr, fipc,user, datea, fiptm)
values(schema.seq_tddr.nextval, old.fipc,'A', systimestamp, v_pr);
select pidr
into v_pkdocid_r
from tddr
where fiptm = v_pr;
insert into schema.tere(pidr, ferror, fidre, user, datea, fipcm)
values(schema.seq_tere.nextval, v_fkerrorID, v_pkdocid_r, 'A', SYSTIMESTAMP, v_linerror);
END IF;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END trg_CP;
When i run the script, i get the error:
PL/SQL: ORA-00984: column not allowed in here,
which is referred to the select attr into variable
How can i bypass the error? Is The syntax wrong?
EDIT 15-09-2022 15:31
with suggested changes, now i get:
PLS-00382: expression is of wrong type
in begin statement.
My trigger is now like this:
create or replace trigger schema.trg_CP
after insert on tdlrp
referencing old as old
for each row
---------------------------------------------------------------------------------------------------------
declare
v_fkidnc schema.tdlrp.fkidnc%type;
v_errortype schema.tdlrp.xerrort%type;
v_fkerrorID schema.tepm.ferror%type;
v_linerror number;
v_pr schema.tpm.pipm%type;
v_pkdocid_r schema.tddr.pidr%type;
---------------------------------------------------------------------------------------------------------
begin
select fkidnc, xerrort
into v_fkidnc, v_errortype
from schema.tdlrp;
--
if :new.fkidnc = 1 and :new.errortype = 1 then
select ferror, fipcm
into v_fkerrorID, v_linerror
from schema.tepm;
select pipm
into v_pr
from schema.tpm
where fipcm = v_linerror;
insert into schema.tddr(pidr, fipc,user, datea, fiptm)
values(schema.seq_tddr.nextval, old.fipc,'A', systimestamp, v_pr);
select pidr
into v_pkdocid_r
from tddr
where fiptm = v_pr;
insert into schema.tere(pidr, ferror, fidre, user, datea, fipcm)
values(schema.seq_tere.nextval, v_fkerrorID, v_pkdocid_r, 'A', SYSTIMESTAMP, v_linerror);
END IF;
--
EXCEPTION
WHEN OTHERS THEN
RAISE;
END trg_CP;
I believe this select
select fkidnc, xerrort into v_fkidnc, v_errortype from schema.tdlrp;
is gonna return many rows and you are trying to assign it to a variable and but need to be assigned to an array of value.
it looks for me that you want to compare the new value inserted, so no need to make select on the same table actually oracle doesn't allow that
you should use
if :new.fkidnc = 1 then
--your logic
end if;
Try to see the code below, I am trying to edit it as I can, because I don't know how your tables are
create or replace trigger schema.trg_CP
after insert on tdlrp
referencing old as old
for each row
---------------------------------------------------------------------------------------------------------
declare
v_fkerrorID schema.tepm.ferror%type;
v_linerror number;
v_pr schema.tpm.pipm%type;
v_pkdocid_r schema.tddr.pidr%type;
---------------------------------------------------------------------------------------------------------
begin
if inserting then
--
if :new.fkidnc = 1 and :new.errortype = 1 then
select ferror, fipcm
into v_fkerrorID, v_linerror
from schema.tepm; -- you should use a condition to return 1 values
select pipm
into v_pr
from schema.tpm
where fipcm = v_linerror --this can return error in execution because can return many values;
insert into schema.tddr(pidr, fipc,user, datea, fiptm)
values(schema.seq_tddr.nextval, old.fipc,'A', systimestamp, v_pr);
select pidr
into v_pkdocid_r
from tddr
where fiptm = v_pr --this can return error in execution because can return many values;
insert into schema.tere(pidr, ferror, fidre, user, datea, fipcm)
values(schema.seq_tere.nextval, v_fkerrorID, v_pkdocid_r, 'A', SYSTIMESTAMP, v_linerror);
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END trg_CP;
create or replace trigger schema.trg_CP
after insert on tdlrp
referencing old as old
for each row
---------------------------------------------------------------------------------------------------------
declare
v_fkerrorID schema.tepm.ferror%type;
v_linerror number;
v_pr schema.tpm.pipm%type;
v_pkdocid_r schema.tddr.pidr%type;
---------------------------------------------------------------------------------------------------------
begin
--
if :new.fkidnc = 1 and :new.errortype = 1 then
select ferror, fipcm
into v_fkerrorID, v_linerror
from schema.tepm where --some condition to return 1 row of ferror,fipcm;
select pipm
into v_pr
from schema.tpm
where fipcm = v_linerror;
insert into schema.tddr(pidr, fipc,user, datea, fiptm)
values(schema.seq_tddr.nextval, :old.fipc,'A', systimestamp, v_pr);
select pidr
into v_pkdocid_r
from tddr
where fiptm = v_pr;
insert into schema.tere(pidr, ferror, fidre, user, datea, fipcm)
values(schema.seq_tere.nextval, v_fkerrorID, v_pkdocid_r, 'A', SYSTIMESTAMP, v_linerror);
END IF;
--
EXCEPTION WHEN OTHERS THEN RAISE;
END trg_CP;
Related
We have an stored procedure to transfer the data(contract data) from database 1 to database 2(interfacing with SAP to Intermeidate Database , then our database), and this contain loops and more that one table in the execution.And we have an PB12.5 desktop application with several modules like procurement,crewing, employee etc.The issue is here while executing the stored procedure from MSSQL using exec, it will take nearly 2 minutes depend on the recieved data from SAP.During the execution I'm unable to open procurement window and it is opening once the stored procedure completed the execution.The other side employee window is opening without any issue.The below are my findings/comments
Procurement module is using table1 and table2 , but in the stored procedure we are not using any of this tables.We are using table 3 and table 4(but later we will use the table from procurement module in proc)
2.While executing the proc Im able to select the tables from procurement module using select * from table1.
3.None of the table is locking from proc.
4.We have tried the same scenarios from different PC same issue exist.
5.Later we will extend the stored procedure with more tables and multiple loops(cursor)
Below are the small part of procedure(we have to extend more and it is hold now because of this issue)
Many thanks in advance.
alter PROC [spectwosuite].[CST_GENERATE_IPurchase_contract]
as begin
SET NOCOUNT ON;
/**/
--truncate table spectwosuite.CUSTOM_SAP_CONTRACT_ITEM;
--truncate table spectwosuite.CUSTOM_SAP_CONTRACT_header;
--truncate table spectwosuite.CUSTOM_SAP_PROC_LOG;
--Variable declaration
DECLARE #MATERIALNO VARCHAR(20);
DECLARE #PURCHASEDOCNO VARCHAR(20);
DECLARE #PORTID NUMERIC(15);
DECLARE #PRICE DECIMAL(11,2);
DECLARE #PKID NUMERIC(16);
DECLARE #STOCKTYPEID NUMERIC(15);
DECLARE #STOCKTYPECODE VARCHAR(50);
DECLARE #STNAME VARCHAR(50);
DECLARE #UNITID NUMERIC(15);
DECLARE #BUSFLOWID NUMERIC(15);
DECLARE #BUSSTATUSID NUMERIC(15);
DECLARE #ITEMNO VARCHAR(5);
DECLARE #SUBITEMNO VARCHAR(10);
DECLARE #STOCKDISID NUMERIC(15);
DECLARE #PURCONTRACTID NUMERIC(15);
DECLARE #REVISIONNO NUMERIC(15);
DECLARE #DESCR NVARCHAR(100);
DECLARE #ADDRESSID NUMERIC(15);
DECLARE #DELTERMSID NUMERIC(15);
DECLARE #PAYTERMSID NUMERIC(15);
DECLARE #VALIDSTART DATETIME;
DECLARE #VALIDEND DATETIME;
DECLARE #CURRENCY NCHAR(3);
DECLARE #PRODUCTGROUPID NUMERIC(15);
DECLARE #PURCONTRACTPRODUCTGROUPID NUMERIC(15);
DECLARE #MATERIALGRP NVARCHAR(20);
DECLARE #NETPRICE NUMERIC(16,6);
DECLARE #BASEPRICE NUMERIC(16,6);
DECLARE #PRODUCTGROUPLINEID NUMERIC(15);
DECLARE #SECTION VARCHAR(20);
DECLARE #PUREXIST NUMERIC(1);
DECLARE #HEADERPKID NUMERIC(16);
DECLARE #ITEMPRICE NUMERIC(16,6);
DECLARE #BASEITEMPRICE NUMERIC(16,2);
DECLARE #PURCONTRACTVARIABLEID NUMERIC(15);
DECLARE #FACTORVALUE NUMERIC(9,4);
DECLARE #ITEMPERCENTAGE NUMERIC(15,2);
DECLARE #ITEMPRICEDIFF1 NUMERIC(15,2);
DECLARE #ITEMPRICEDIFF2 NUMERIC(15,2);
DECLARE #ITEMPKID NUMERIC(16);
/*CONT1: Transfering all the portid and purchase document number to different table */
--PRINT 'CONT1 START'
--PRINT GETDATE();
BEGIN TRY
--BEGIN TRANSACTION
--BEGIN
SET #SECTION='CONT1';
BEGIN TRANSACTION CONT1
INSERT INTO SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_PORT
(PORTID
,PURCHASE_DOC_NO
)
SELECT DISTINCT PORTID,PURCHASE_DOC_NO FROM SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK) WHERE IMPORT_STATUS IS NULL and DELETION_IND NOT IN('L','1')
and portid>0 and MATERIAL_NO<>'' and FACTOR>0 and
not exists (select PORTID from SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_PORT where PORTID=SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_PORT.PORTID
and PURCHASE_DOC_NO =SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_PORT.PURCHASE_DOC_NO) ORDER BY PURCHASE_DOC_NO,PORTID ASC;
COMMIT TRANSACTION CONT1
--END
----INSERT INTO spectwosuite.CUSTOM_SAP_PROC_LOG
---- (STATUS
---- ,DESCRIPTION
---- ,PROCESSEDDATE
---- ,RECORDCOUNT)
---- VALUES
---- (1,
---- 'CONT1'
---- ,GETDATE()
---- ,##ROWCOUNT
---- );
--PRINT 'CONT1 END'
--PRINT GETDATE();
/* CONT1 END */
/*CONT2 Inserting new item which one dont have price in all ports*/
/*Variable declaration*/
--PRINT 'CONT2 START'
--PRINT GETDATE();
-- BEGIN
SET #SECTION='CONT2';
--SELECT DISTINCT CAST(MATERIAL_NO AS VARCHAR(20))AS MATERIAL_NO,PURCHASE_DOC_NO FROM SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK) WHERE PURCHASE_DOC_NO='4600000820' and IMPORT_STATUS IS NULL and MATERIAL_NO<>'' and DELETION_IND NOT IN('L','1') and len(material_no)>0 and factor>0 and portid>0 ORDER BY MATERIAL_NO,PURCHASE_DOC_NO ASC;
DECLARE CONT2CR CURSOR FOR
SELECT DISTINCT CAST(MATERIAL_NO AS VARCHAR(20))AS MATERIAL_NO,PURCHASE_DOC_NO FROM SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK) WHERE IMPORT_STATUS IS NULL and MATERIAL_NO<>'' and DELETION_IND NOT IN('L','1') and len(material_no)>0 and factor>0 and portid>0 ORDER BY MATERIAL_NO,PURCHASE_DOC_NO ASC;
OPEN CONT2CR
FETCH NEXT FROM CONT2CR INTO #MATERIALNO,#PURCHASEDOCNO
WHILE ##FETCH_STATUS=0
BEGIN
BEGIN TRAN CONT2
select #PKID=MIN(pk_id),#PRICE=MIN(NET_PRICE) from SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK) WHERE MATERIAL_NO=#MATERIALNO AND PURCHASE_DOC_NO=#PURCHASEDOCNO and IMPORT_STATUS IS NULL and DELETION_IND NOT IN('L','1') and factor>0 and portid>0;
/*Retreiving port details table*/
DECLARE CONT2PORTCR CURSOR FOR
SELECT DISTINCT portid FROM SAP_INTERFACE.spectwosuite.custom_sap_contract_port WITH(NOLOCK) WHERE (SAP_INTERFACE.spectwosuite.custom_sap_contract_port.purchase_doc_no = #PURCHASEDOCNO) and ( custom_sap_contract_port.portid > 0 ) ;
OPEN CONT2PORTCR
FETCH NEXT FROM CONT2PORTCR INTO #PORTID
WHILE #PORTID>0
BEGIN
IF #PORTID>0
BEGIN
BEGIN TRAN
/*Insert Script*/
SET #SECTION='ITEM_ADDITION';
IF (select COUNT(*) from SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK) where MATERIAL_NO=CAST(#MATERIALNO AS varchar(20)) AND PORTID=#PORTID and PURCHASE_DOC_NO=#PURCHASEDOCNO and IMPORT_STATUS IS NULL and DELETION_IND NOT IN('L','1') and factor>0 and portid>0)<=0
BEGIN
INSERT INTO SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM
(DELETION_IND,PURCHASE_DOC_NO,ITEM_NO,MATERIAL_NO,SHORT_TEXT,MATERIAL_GRP,QTY,UOM,NET_PRICE,PORTID,TEMPPORTID,FACTOR)
select DELETION_IND,PURCHASE_DOC_NO,ITEM_NO,MATERIAL_NO,SHORT_TEXT,MATERIAL_GRP,QTY,UOM,NET_PRICE,#PORTID,1252,FACTOR from SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK) WHERE pk_id=#PKID and DELETION_IND<>'1' and IMPORT_STATUS IS NULL;
END
SET #PORTID=0;
COMMIT TRAN
END
FETCH NEXT FROM CONT2PORTCR INTO #PORTID
END
CLOSE CONT2PORTCR
DEALLOCATE CONT2PORTCR
COMMIT TRAN CONT2
FETCH NEXT FROM CONT2CR INTO #MATERIALNO,#PURCHASEDOCNO
END
CLOSE CONT2CR
DEALLOCATE CONT2CR
--END
--INSERT INTO spectwosuite.CUSTOM_SAP_PROC_LOG
-- (STATUS
-- ,DESCRIPTION
-- ,PROCESSEDDATE
-- ,RECORDCOUNT)
-- VALUES
-- (1,
-- 'CONT2'
-- ,GETDATE()
-- ,##ROWCOUNT
-- );
--PRINT 'CONT2 END'
--PRINT GETDATE();
/*CONT2 END*/
/*CONT3*/
--PRINT 'CONT3 START'
--PRINT GETDATE();
SET #SECTION='CONT3';
BEGIN TRAN CONT3
INSERT INTO spectwosuite.CUSTOM_SAP_CONTRACT_HEADER
(TABLEPKID
,PURCHASE_DOC_NO
,COMPANY_CODE
,CREATED_ON_DATE
,VENDOR_CODE
,PAYMENT_TERMS
,PURCHASE_GRP
,VALIDITY_START
,VALIDITY_END
,YOUR_REFERENCE
,OUR_REFERNCE
,TARGET_AMOUNT
,CURRENCY
,DESCRIPTION
,SHIPCODE
,STATUS
,CREATEDATE
,VALIDATESTART
,VALIDATEEND
,INTERNAL_STATUS
,INTERNAL_MESSAGE
)
SELECT
PK_ID
,PURCHASE_DOC_NO
,COMPANY_CODE
,CREATED_ON_DATE
,VENDOR_CODE
,PAYMENT_TERMS
,PURCHASE_GRP
,VALIDITY_START
,VALIDITY_END
,YOUR_REFERENCE
,OUR_REFERNCE
,TARGET_AMOUNT
,CURRENCY
,DESCRIPTION
,SHIPCODE
,STATUS
,CREATEDATE
,VALIDATESTART
,VALIDATEEND
,INTERNAL_STATUS
,INTERNAL_MESSAGE
FROM SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_HEADER WITH(NOLOCK)
where import_status is null and purchase_doc_no<>'' and validity_start<>'' and validity_end<>'' and currency<>''and status>0
and not exists(select pk_id from spectwosuite.CUSTOM_SAP_CONTRACT_HEADER WHERE TABLEPKID= SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_HEADER.PK_ID)
COMMIT TRAN CONT3
--INSERT INTO spectwosuite.CUSTOM_SAP_PROC_LOG
-- (STATUS
-- ,DESCRIPTION
-- ,PROCESSEDDATE
-- ,RECORDCOUNT)
-- VALUES
-- (1,
-- 'CONT3'
-- ,GETDATE()
-- ,##ROWCOUNT
-- );
--PRINT 'CONT3 END'
--PRINT GETDATE();
/*CONT3 END*/
/*CONT4*/
--PRINT 'CONT4 START'
--PRINT GETDATE();
SET #SECTION='CONT4';
BEGIN TRAN CONT4
INSERT INTO spectwosuite.CUSTOM_SAP_CONTRACT_ITEM
(TABLEPKID,PURCHASE_DOC_NO
,ITEM_NO
,DELETION_IND
,MATERIAL_NO
,SHORT_TEXT
,MATERIAL_GRP
,QTY
,UOM
,NET_PRICE
,PORTID
,STOCKTYPEID
,INTERNAL_MESSAGE
,INTERNAL_STATUS
,CONTRACTTYPE
,AGREEMENTSUBITEMNO
,FACTOR
)
select PK_ID,PURCHASE_DOC_NO
,ITEM_NO
,DELETION_IND
,MATERIAL_NO
,SHORT_TEXT
,MATERIAL_GRP
,QTY
,UOM
,NET_PRICE
,PORTID
,STOCKTYPEID
,INTERNAL_MESSAGE
,INTERNAL_STATUS
,CONTRACTTYPE
,AGREEMENTSUBITEMNO
,FACTOR
from SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM WITH(NOLOCK)
where IMPORT_STATUS is null and MATERIAL_NO<>'' and DELETION_IND<>'L' AND PORTID>0 and FACTOR>0 and LEN(SHORT_TEXT)>0 AND LEN(PURCHASE_DOC_NO)>0 AND
not exists (select PK_ID from spectwosuite.CUSTOM_SAP_CONTRACT_ITEM where TABLEPKID= SAP_INTERFACE.spectwosuite.CUSTOM_SAP_CONTRACT_ITEM.PK_ID ) ORDER BY PK_ID ASC;
COMMIT TRAN CONT4
-- /*Inserting History*/
-- /*Transfering process status to interface table.*/
TRUNCATE TABLE spectwosuite.CUSTOM_SAP_CONTRACT_HEADER;
TRUNCATE TABLE spectwosuite.CUSTOM_SAP_CONTRACT_ITEM;
DELETE FROM spectwosuite.CUSTOM_SAP_PROC_LOG WHERE STATUS=99;
COMMIT
-- /*PURCHASE CONTRACT CREATION END*/
-- SET NOCOUNT OFF;
-- --COMMIT TRANSACTION
END TRY
BEGIN CATCH
DECLARE #ERRORNUMBER VARCHAR(20);
DECLARE #ERRMSG VARCHAR(MAX);
SET #ERRORNUMBER=CAST(ERROR_LINE() AS VARCHAR(20));
SET #ERRMSG=ERROR_MESSAGE();
BEGIN TRAN ER
INSERT INTO spectwosuite.CUSTOM_SAP_PROC_LOG
(STATUS
,DESCRIPTION
,PROCESSEDDATE
,RECORDCOUNT
,ERRORMSG)
VALUES
(
88,
#SECTION
,getdate()
,1
,#ERRORNUMBER +','+ #ERRMSG
);
COMMIT TRAN ER
END CATCH
END
Try to add Begin tran and commit Tran without success
How can you improve this without using a cursor? I was thinking using table variable would help, but am I going right direction doing so? I have omitted cursor and try to do it with table variable. Please help, here is the code.
IF EXISTS (SELECT * FROM sysobjects WHERE id = object_id(N'[dbo].[BatchProcessBridge_CustomerEvent]') AND [xtype] IN (N'P'))
BEGIN
DROP PROCEDURE [dbo].[BatchProcessBridge_CustomerEvent]
END
GO
CREATE PROCEDURE [dbo].[BatchProcessBridge_CustomerEvent]
(
#BatchJobTable Bridge_CustomerEventBatchJobTable READONLY,
#Name VARCHAR(50)
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Lsn BINARY(10),
DECLARE #SeqVal BINARY(10),
DECLARE #Action VARCHAR(300),
DECLARE #CustId VARCHAR(MAX)
--using tabel variable. Cursor gives bad performance.
DECLARE #TEMP_TABLE TABLE ( [Lsn] BINARY(10), [SeqVal] BINARY(10), [Action] VARCHAR(300), [CustId] VARCHAR(MAX))
INSERT INTO #TEMP_TABLE
SELECT Lsn, SeqVal, [Action], [CustId] FROM #BatchJobTable
--DECLARE GetBatchJobCursor CURSOR FAST_FORWARD
--FOR
--SELECT Lsn, SeqVal, [Action], [CustId] FROM #BatchJobTable
--OPEN GetBatchJobCursor
--FETCH NEXT FROM GetBatchJobCursor INTO #Lsn, #SeqVal, #Action, #CustId
--WHILE ##FETCH_STATUS = 0
BEGIN
BEGIN TRY
BEGIN TRANSACTION
IF (#Action = 'create')
BEGIN
-- Create.
INSERT INTO [Bridge_Customer]
(
[CustId]
,[PersonId]
,[DisplayName]
,[CreatedDate]
,[ModifiedDate]
)
SELECT
[CustId]
,[PersonId]
,[DisplayName]
,[CreatedDate]
,[ModifiedDate]
FROM
#BatchJobTable
WHERE
(Lsn = #Lsn) AND (SeqVal = #SeqVal)
END
ELSE IF (#Action = 'update')
BEGIN
-- Update.
UPDATE [Target]
SET
[Target].[CustId] = [Ref].[CustId]
,[Target].[PersonId] = [Ref].[PersonId]
,[Target].[DisplayName] = [Ref].[DisplayName]
,[Target].[CreatedDate] = [Ref].[CreatedDate]
,[Target].[ModifiedDate] = [Ref].[ModifiedDate]
FROM
[dbo].[Bridge_Customer] AS [Target]
INNER JOIN
(SELECT * FROM #BatchJobTable WHERE (Lsn = #Lsn) AND (SeqVal = #SeqVal)) AS [Ref]
ON
([Target].[CustId] = [Ref].[CustId])
END
ELSE IF (#Action = 'delete')
BEGIN
DELETE FROM [dbo].[Bridge_Customer] WHERE [CustId] = #CustId
END
-- Update last processed event.
EXEC [dbo].[UpdateLastProcessedEvent]
#Name = #Name,
#Lsn = #Lsn,
#SeqVal = #SeqVal
COMMIT TRANSACTION
END TRY
BEGIN CATCH
DECLARE #ErrorMessage NVARCHAR(4000);
DECLARE #ErrorSeverity INT;
DECLARE #ErrorState INT;
SELECT
#ErrorMessage = ERROR_MESSAGE(),
#ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE();
-- Use RAISERROR inside the CATCH block to return error
-- information about the original error that caused
-- execution to jump to the CATCH block.
RAISERROR (#ErrorMessage, -- Message text.
#ErrorSeverity, -- Severity.
#ErrorState -- State.
);
ROLLBACK TRANSACTION
END CATCH
--FETCH NEXT FROM GetBatchJobCursor INTO #Lsn, #SeqVal, #Action, #CustId
END
--CLOSE GetBatchJobCursor
--DEALLOCATE GetBatchJobCursor
END
GO
A cursor is not necessary here; this is just basic SQL. Forgive any mistakes with my code as you haven't provided any DLL but I'm pretty sure you can just do this:
IF (#Action = 'create')
INSERT INTO Bridge_Customer
(
CustId
,PersonId
,DisplayName
,CreatedDate
,ModifiedDate
)
SELECT
CustId
,PersonId
,DisplayName
,CreatedDate
,ModifiedDate
FROM #BatchJobTable
ELSE IF (#Action = 'update')
UPDATE tgt
SET tgt.CustId = Ref.CustId
,tgt.PersonId = Ref.PersonId
,tgt.DisplayName = Ref.DisplayName
,tgt.CreatedDate = Ref.CreatedDate
,tgt.ModifiedDate = Ref.ModifiedDate
FROM dbo.Bridge_Customer AS tgt
INNER JOIN #BatchJobTable AS ref
ON (tgt.CustId = Ref.CustId)
ELSE IF (#Action = 'delete')
DELETE FROM dbo.Bridge_Customer
WHERE CustId IN (SELECT CustId FROM #BatchJobTable);
Personally, I would split this into three stored and call whichever one from the application layer. What you are doing is known as a "Catch All query" which is fine but, if you must go that route, read this: Catch All Queries (Gail Shaw)
I have table with a myNumber varchar(50) column which stores values with lead zero, like a '0000001111'.
Now I want to replace leading '0000' with '12', like '12001111'.
I tried this statement:
UPDATE myDB.dbo.myTable
SET myNumber = REPLACE(myNumber, '0000', '12')
WHERE myNumber LIKE '0000%'
But this caused an error:
Msg 248, Level 16, State 1, Procedure trplist_for_Inserted_Updated_Deleted Line 80
The conversion of the varchar value "831116399075' overflowed an int column.
Why this error caused if all columns are the varchar?
What should I do?
UPDATED
Sorry guys, the reason of error it is the tables trigger.
Here is triggers logic
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER TRIGGER [dbo].[trplist_for_Inserted_Updated_Deleted]
ON [dbo].[pList]
FOR Insert, Update, Delete
NOT FOR REPLICATION
AS
SET NOCOUNT ON
Declare #Result_check Int
Declare #NameTable nvarchar(30)
set #NameTable='plist'
Declare #FieldName nvarchar(30)
set #FieldName='ChangeTime'
Declare #Columns varbinary(MAX)
set #Columns=COLUMNS_UPDATED()
Execute CheckChangeFields #Columns, #NameTable, #FieldName, #Result_check
if #Result_check = 1
begin
return
end
set #FieldName='DateTimeInArchive'
Execute CheckChangeFields #Columns, #NameTable, #FieldName, #Result_check
if #Result_check = 1
begin
return
end
Declare #stateRecord Int
IF EXISTS(SELECT * FROM inserted)
IF EXISTS(SELECT * FROM deleted)
BEGIN
SET #stateRecord = 1 --Update
--PRINT 'Update'
END
ELSE
BEGIN
--PRINT 'Insert'
SET #stateRecord = 0 --Insert
END
ELSE
BEGIN
--PRINT 'Is DELETE'
IF EXISTS(SELECT * FROM deleted)
BEGIN
SET #stateRecord = 2 --Delete
--PRINT 'DELETE'
END
ELSE
BEGIN
SET #stateRecord = -1
--PRINT 'No DELETE'
END
END
IF #stateRecord = -1
RETURN
declare #id_value int
Declare #status_record int
declare #inn int
declare #Company int
declare #tabnumber varchar(50)
if (#stateRecord in (0,1))
BEGIN
--inserted or updated
--проверка на изменение поля StatusRecord
declare #Result_check_status_record int
if Exists(select * from Deleted where checksum(StatusRecord) In (select Checksum(StatusRecord) from Inserted))
select #Result_check_status_record= 1--одинаковые
else
select #Result_check_status_record= 0--разные
DECLARE cursor_inserted_trpList_Inserted_Updated_Delete_logs CURSOR LOCAL FOR select id, StatusRecord, INN, TabNumber, Company from inserted
OPEN cursor_inserted_trpList_Inserted_Updated_Delete_logs
FETCH NEXT FROM cursor_inserted_trpList_Inserted_Updated_Delete_logs INTO #id_value, #status_record,#inn, #tabnumber, #Company
WHILE ##FETCH_STATUS = 0
BEGIN
if (#inn<>'')
begin
if Exists(select id from plist where (id<> #id_value) and (INN=#inn))
begin
RollBack
RAISERROR('Данный INN уже имеется в базе', 16,2)
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
return
end
end
if (#tabnumber<>'') and (#tabnumber<>'0')
begin
if #Company = 0
begin
if Exists(select id from plist where (id<> #id_value) and (TabNumber=#tabnumber) and (Company<=0))
begin
RollBack
RAISERROR('Данный TabNumber уже имеется в базе', 16,2)
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
return
end
end
else
begin
if Exists(select id from plist where (id<> #id_value) and (TabNumber=#tabnumber) and (Company=#Company))
begin
RollBack
RAISERROR('Данный TabNumber уже имеется в базе в данном подразделении', 16,2)
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
return
end
end
end
if ((#status_record&1)>0)
begin
if (#Result_check_status_record=0)
begin
Execute GustIsRelease #id_value
update guest set IDNoFace=0 where PListID=#id_value
Declare #dmtm datetime
if Exists(select id from plist where (id=#id_value) and (IsNull(DateTimeInArchive, '')=''))
begin
Update plist set DateTimeInArchive=GetDate() where (id=#id_value) and (IsNull(DateTimeInArchive, '')='')
end
end
end
else
begin
if Exists(select id from plist where (id=#id_value) and (IsNull(DateTimeInArchive, 1)<>1))
Update plist set DateTimeInArchive=Null where (id=#id_value) and (IsNull(DateTimeInArchive, 1)<>1)
end
FETCH NEXT FROM cursor_inserted_trpList_Inserted_Updated_Delete_logs INTO #id_value, #status_record,#inn, #tabnumber, #Company
END
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
END
if (#stateRecord=2)
BEGIN
DECLARE cursor_inserted_trpList_Inserted_Updated_Delete_logs CURSOR LOCAL FOR select id from deleted
OPEN cursor_inserted_trpList_Inserted_Updated_Delete_logs
FETCH NEXT FROM cursor_inserted_trpList_Inserted_Updated_Delete_logs INTO #id_value
WHILE ##FETCH_STATUS = 0
BEGIN
if Exists(select id from pmark where owner=#id_value)
begin
RollBack
RAISERROR('У сотрудника остались активные пароли', 16,2)
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
return
end
if Exists(select id from guest where IDNoFace=#id_value)
begin
RollBack
RAISERROR('Сотрудник привязан к посетителю', 16,2)
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
return
end
update guest set IDNoFace=0 where IDNoFace=#id_value
update guest set ReceiveListId=0 where ReceiveListId=#id_value
FETCH NEXT FROM cursor_inserted_trpList_Inserted_Updated_Delete_logs INTO #id_value
END
CLOSE cursor_inserted_trpList_Inserted_Updated_Delete_logs
END
You could use STUFF
UPDATE myDB.dbo.myTable
SET myNumber=stuff(myNumber, 1,4, '12')
WHERE myNumber LIKE '0000%'
Use can use SUBSTRING/STUFF as below:
SUBSTRING:
UPDATE #tblTest
SET Number='12'+SUBSTRING(Number,5,LEN(NUMBER))
WHERE LEFT(Number,4)='0000'
AND LEN(Number)>4
STUFF:
UPDATE #tblTest
SET Number=STUFF(Number, 1,4, '12')
WHERE LEFT(Number,4)='0000'
AND LEN(Number)>4
Use substring function to accomplish the result u want
UPDATE myDB.dbo.myTable
SET Number='12'+SUBSTRING(myNumber,5)
WHERE SUBSTRING(myNumber,1,4)='0000';
Can someone please advise why the first transaction fails and the second succeeds, I've been stuck on this for a while now
GO
DECLARE #errnum AS int;
BEGIN TRAN;
SET IDENTITY_INSERT Production.Products ON;
INSERT INTO Production.Products(productid, productname, supplierid,
categoryid, unitprice, discontinued)
VALUES(1, N'Test1: Ok categoryid', 1, 1, 18.00, 0);
SET #errnum = ##ERROR;
IF #errnum <> 0
BEGIN
IF ##TRANCOUNT > 0 ROLLBACK TRAN;
PRINT 'Insert #1 into Production.Products failed with error ' +
CAST(#errnum AS VARCHAR);
END;
INSERT INTO Production.Products(productid, productname, supplierid,
categoryid,unitprice, discontinued)
VALUES(101, N'Test2: Bad categoryid', 1, 1, 18.00, 0);
SET #errnum = ##ERROR;
IF #errnum <> 0
BEGIN
IF ##TRANCOUNT > 0 ROLLBACK TRAN;
PRINT 'Insert #2 into Production.Products failed with error ' +
CAST(#errnum AS VARCHAR);
END;
SET IDENTITY_INSERT Production.Products OFF;
From the looks of it I've wrapped everything in the proper BEGIN...END statements, however the code goes through and executes almost every single line of code. I've done print statements too to make sure that both #rows variables actually do contain values greater than 0. Can anyone help point me in the right direction?
IF #rows > '0'
--This agent's Tax ID number has been found to exist in AgentIdentification table
BEGIN
--Set UniqueAgentId according to mapped value from AgentIdentification table
SELECT #uniqueAgentId = UniqueAgentId
FROM AgentIdentification
WHERE AgentTaxId = #ssn
--Check to make sure this record exists in UniqueAgentIdToAgentId table
SELECT #rows = COUNT(*)
FROM UniqueAgentIdToAgentId
WHERE UniqueAgentId = #uniqueAgentId and AgentId = #agentId
PRINT #rows
IF #rows > 0
--Record exists in UniqueAgentIdToAgentId table
--Check to make sure correct UniqueAgentId is mapped to correct AgentId and vice versa
BEGIN
SELECT #agentIdRows = COUNT(AgentId)
FROM UniqueAgentIdToAgentId
WHERE UniqueAgentId = #uniqueAgentId and AgentId <> #agentId
SELECT #uniqueIdRows = COUNT(UniqueAgentId)
FROM UniqueAgentIdToAgentId
WHERE AgentId = #agentId and UniqueAgentId <> #uniqueAgentId
IF #uniqueIdRows = 0 AND #agentIdRows = 0
BEGIN
SET #returnValue = 1
END
ELSE IF #agentIdRows = 0 AND #uniqueIdRows > 0
BEGIN
SET #returnValue = 2
END
ELSE
BEGIN
SET #returnValue = 3
END
END
--Record does not exist in UniqueAgentIdToAgentId and will be added
ELSE
BEGIN
INSERT INTO UniqueAgentIdToAgentId (UniqueAgentId, AgentId, CompanyCode, LastChangeOperator, LastChangeDate)
VALUES (#uniqueAgentId, #agentId, #companyCode, #lastChangeOperator, #LastChangeDate)
SET #returnValue = 4
END
END
ELSE
BEGIN TRANSACTION
--This agent Tax ID number does not exist on AgentIdentification table
--Add record into Agent and AgentIdentification table
INSERT INTO Agent (EntityType, FirstName, LastName, NameSuffix, CorporateName, LastChangeOperator, LastChangeDate)
VALUES (#entityType, #firstName, #lastname, '', #corporateName, #lastChangeOperator, #LastChangeDate)
SELECT #uniqueAgentId = ##IDENTITY
SELECT UniqueAgentId
FROM Agent
INSERT INTO AgentIdentification (UniqueAgentId, TaxIdType, AgentTaxId, LastChangeOperator, LastChangeDate)
VALUES (#uniqueAgentId, #taxIdType, #ssn, #lastChangeOperator, #lastChangeDate)
--Check to make sure this record exists in UniqueAgentIdToAgentId table
SELECT #rows = COUNT(*)
FROM UniqueAgentIdToAgentId
WHERE UniqueAgentId = #uniqueAgentId and AgentId = #agentId
IF #rows > 0
--Record exists in UniqueAgentIdToAgentId table
--Check to make sure correct UniqueAgentId is mapped to correct AgentId and vice versa
BEGIN
SELECT #agentIdRows = COUNT(AgentId)
FROM UniqueAgentIdToAgentId
WHERE UniqueAgentId = #uniqueAgentId and AgentId <> #agentId
SELECT #uniqueIdRows = COUNT(UniqueAgentId)
FROM UniqueAgentIdToAgentId
WHERE AgentId = #agentId and UniqueAgentId <> #uniqueAgentId
IF #uniqueIdRows = 0 AND #agentIdRows = 0
BEGIN
SET #returnValue = 5
END
ELSE IF #agentIdRows = 0 AND #uniqueIdRows > 0
BEGIN
SET #returnValue = 6
END
ELSE
BEGIN
SET #returnValue = 7
END
END
--Record does not exist in UniqueAgentIdToAgentId and will be added
ELSE
BEGIN
INSERT INTO UniqueAgentIdToAgentId (UniqueAgentId, AgentId, CompanyCode, LastChangeOperator, LastChangeDate)
VALUES (#uniqueAgentId, #agentId, #companyCode, #lastChangeOperator, #LastChangeDate)
SET #returnValue = 8
END
COMMIT TRANSACTION
I think this:
ELSE
BEGIN TRANSACTION
Needs to be this:
ELSE
BEGIN
BEGIN TRANSACTION
And this:
COMMIT TRANSACTION
Needs to be this:
COMMIT TRANSACTION
END