update query does not update the values into temporary table in mysql.
DECLARE _defaultDateTime DATETIME;
DECLARE _resourceTypeId CHAR(36);
DECLARE _billedUsageHrs DECIMAL(15,6);
DECLARE _unbilledusageHrs DECIMAL(15,6);
DECLARE _billedCost DECIMAL(15,6);
DECLARE _unBilledCost DECIMAL(15,6);
DECLARE _resourceIdentifier CHAR(36);
DROP TABLE IF EXISTS _usageTable;
CREATE TEMPORARY TABLE _usageTable(resourceinstanceId CHAR(36),billedusageinHrs DECIMAL(15,6), billedusageCost DECIMAL(15,6), unBilledusageinHrs DECIMAL(15,6), unbilledusageCost DECIMAL(15,6)) ENGINE=MEMORY;
UPDATE _usageTable SET resourceinstanceId = 'a17b5e49-000c-11e3-8bfa-842b2bac06e5' WHERE 1 = 1;
SELECT resourceinstanceId, billedusageinHrs, billedusageCost, unBilledusageinHrs, unbilledusageCost FROM _usageTable;
The above stored procedure returns empty row
CREATE TEMPORARY TABLE _usageTable(resourceinstanceId CHAR(36),
billedusageinHrs DECIMAL(15,6),
billedusageCost DECIMAL(15,6),
unBilledusageinHrs DECIMAL(15,6),
unbilledusageCost DECIMAL(15,6)) ENGINE=MEMORY;
UPDATE _usageTable SET resourceinstanceId = 'a17b5e49-000c-11e3-8bfa-842b2bac06e5' WHERE 1 = 1;
UPDATE will update existing rows.
As far as I can see, you just created the table. So it is empty. There is simply no row to update.
Perhaps are you looking for INSERT instead of UPDATE ? Or maybe you example does not put emphasis on the real problem?
Related
I am relatively new to MySQL stored Procedures. I have a stored procedure that works fine in certain conditions and not in other. I'm a bit confused that what causes the error. It is a entity processing SP, based on certain values and conditions it either creates or update entity from data in a staging table.
In conditions when it works fine:
When I only process a single entity.
Works for bulk entries when there is nothing in entity table.
Don't works when:
There are entries in entity table and bulk processing is done. - Error in checking up the already existing entity_id in entity and older entity_id is assigned instead a new one should be created.
(I actually need above scenario to work more frequently than others)
I have tried to keep the code to minimum in order to understand the flow of SP. Please consider all variables as declared. SP might not compile.
CREATE DEFINER=`admin`#`%` PROCEDURE `sp_ent`(test_id int)
BEGIN
-- Move code tables to temp tables
-- Declare all the required variables here
DECLARE counter, len INT;
DECLARE var2 INT;
DECLARE var3 TINYINT(1);
DECLARE var4 DECIMAL(18,4);
DECLARE var5 DATE;
DECLARE var6 VARCHAR(1000);
DECLARE var7 VARCHAR(5000);
DROP TEMPORARY TABLE IF EXISTS `temp_ent`;
IF test_id IS NOT NULL THEN
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_ent` AS (SELECT * FROM `ent_st` WHERE processed = 0 and id=test_id);
ELSE
CREATE TEMPORARY TABLE IF NOT EXISTS `temp_ent` AS (SELECT * FROM `ent_st` WHERE processed = 0);
END IF;
ALTER TABLE `temp_ent` ADD PRIMARY KEY(id);
-- SELECT * FROM `temp_ent`;
DROP TEMPORARY TABLE IF EXISTS `temp_exc`; CREATE TEMPORARY TABLE IF NOT EXISTS `temp_exc` AS (SELECT * FROM `code_exc`);
-- A few more like above
SET counter=1, len=(SELECT COUNT(*) FROM `temp_ent`);
WHILE counter <= len DO
SELECT `id`,var1, var2, var3
INTO v_id,var1, var2, var3
FROM `temp_ent` LIMIT 1;-- WHERE `id` = v_id;
BEGIN
DECLARE insufficient_information CONDITION FOR SQLSTATE '45000';
DECLARE CONTINUE HANDLER FOR insufficient_information SET v_proccessed=1;
SET v_status = CASE
WHEN ... THEN ...
ELSE 'valid'
END;
IF v_status <> 'valid' THEN SIGNAL insufficient_information; END IF;
SELECT `entity_id`,`entity`
INTO v_underlying_entity_id,v_underlying_entity_symbol
FROM `entity` WHERE `entity_id` = v_underlying OR `entity` = v_underlying_entity;
SET v_underlying_entity_symbol = COALESCE(v_underlying_entity_symbol,v_underlying_entity);
SET v_entity = (
CASE
WHEN ... THEN ...
WHEN ... THEN ...
.
.
WHEN ... THEN ...
END
);
SELECT `entity_id`,`entity`
INTO v_entity_id_check,v_entity_check
FROM entity WHERE `entity`=v_entity and `exc`=v_exc;
-- SELECT v_entity_id_check,v_entity_check,v_entity,v_exc;
IF v_entity_check IS NULL THEN
-- SELECT 'Create New Entity and Add';
SET v_entity_id = COALESCE((SELECT MAX(`entity_id`) FROM entity),0) + 1;
SET new_entity = 1;
ELSE
-- SELECT 'Entity Already Present';
SET v_entity_id = v_entity_id_check;
SET new_entity = 0;
END IF;
-- SELECT v_entity_id, v_entity, new_entity;
SET v_name = UPPER(COALESCE(v_name,v_entity));
-- UPDATE entity and underlying/derivatives table
IF new_entity = 1 THEN
-- Insert in respective tables
IF ... THEN
-- SELECT 'Entity Added',v_entity; -- Underlying Entity
INSERT INTO `entity_underlying` (`entity_id`,`entity`,`name`,`exc`,`seg`,`ins`,`isin`,`fo_yn`,`tick`,`lot_size`,`active_yn`)
VALUES (v_entity_id,v_entity,v_name,v_exc,v_seg,v_ins,COALESCE(v_isin,''),COALESCE(v_fo_yn,0),COALESCE(v_tick,0.05),COALESCE(v_lot_size,1),1);
ELSEIF ... THEN
-- SELECT 'Entity Added',v_entity; -- Derivative Entity
INSERT INTO `entity_derivatives` (`entity_id`,`entity`,`name`,`underlying`,`exc`,`seg`,`ins`,`ser`,`isin`,`strike`,`tick`,`lot_size`,`expiry`,`ex_ty`,`active_yn`)
VALUES (v_entity_id,v_entity,v_name,COALESCE(v_underlying_entity_id,-1),v_exc,v_seg,v_ins,COALESCE(v_ser,''),v_isin,COALESCE(v_strike),COALESCE(v_tick,0.05),COALESCE(v_lot_size,-1),v_expiry,v_ex_ty,1);
END IF;
-- Insert in final table
INSERT INTO entity(`entity_id`,`entity`,`exc`,`active_yn`)
VALUES (v_entity_id,v_entity,v_exc,1);
SET v_status='Entity Added';
ELSE
SET v_status='Not a New Entity';
END IF;
END;
UPDATE `ent_st` SET `entity_id`=v_entity_id,`processed`=1,`status`=v_status WHERE id=v_id;
DELETE FROM `temp_ent` WHERE id=v_id;
SET counter = counter +1;
COMMIT;
END WHILE;
END
Any help is highly appreciated. Thanks in advance.
Data comes in via a zip file in a group of csv files which are used to populate holding tables. Some can include new data or updates of existing entries. The holding tables are used for intermediate processing then are used for import to the working tables.
In an effort to speed up the process I have been writing stored procedures to update the working tables. On my laptop one such file with only 730 records is taking about a minute to do its stuff.
I did consider making the 'insert ... on duplicate key update' into a prepared statement inside the SP but some of the other tables have many more fields and I could find no good guide on how to write such a complex one.
Here is my stored procedure:
DROP PROCEDURE IF EXISTS impLuRacodes;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE impLuRacodes()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE v_ATID varchar(10);
DECLARE v_Code varchar(10);
DECLARE v_IssType varchar(10);
DECLARE v_Category varchar(10);
DECLARE v_CNumber int(4);
DECLARE v_CDesc varchar(255);
DECLARE v_ColCode varchar(6);
DECLARE v_LLike int(3);
DECLARE v_LifeS int(3);
DECLARE v_PropS int(3);
DECLARE v_BusS int(3);
DECLARE c_1 CURSOR FOR
SELECT `ATID`, `Code`, `IssType`, `Category`, `CNumber`, `CDesc`, `ColCode`, `LLike`, `LifeS`, `PropS`, `BusS`
FROM lu_racodes_temp;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
OPEN c_1;
REPEAT
FETCH c_1 INTO v_ATID, v_Code, v_IssType, v_Category, v_CNumber,
v_CDesc, v_ColCode, v_LLike, v_LifeS, v_PropS, v_BusS;
INSERT INTO lu_racodes (ATID, `Code`, IssType, Category, CNumber,
CDesc, ColCode, LLike, LifeS, PropS, BusS)
VALUES(v_ATID, v_Code, v_IssType, v_Category, v_CNumber, v_CDesc,
v_ColCode, v_LLike, v_LifeS, v_PropS, v_BusS)
ON DUPLICATE KEY UPDATE
ATID= v_ATID, `Code`= v_Code, IssType= v_IssType, Category= v_Category,
CNumber= v_CNumber, CDesc= v_CDesc, ColCode= v_ColCode, LLike=v_LLike,
LifeS= v_LifeS, PropS= v_PropS, BusS= v_BusS;
UNTIL done END REPEAT;
CLOSE c_1;
END $$
Alternatively, is it possible to put the Select inside the 'Insert ... On Duplicate Key' instead of using a cursor - again something I have had no joy in finding a clear answer to.
Thanks to the guidance I rewrote the code to put the select inside and execution time dropped to 0.156 seconds for a first population. I was concerned about the syntax of the update section with the reference to VALUES as it was a Select statement bringing in the data but changing a couple of rows in the source table did get updated and still with only a 0.235 second time. So here is the code:
DROP PROCEDURE IF EXISTS impLuRacodes;
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE impLuRacodes()
BEGIN
INSERT INTO lu_racodes (`ATID`, `Code`, `IssType`, `Category`, `CNumber`, `CDesc`, `ColCode`, `LLike`, `LifeS`, `PropS`, `BusS`) SELECT `ATID`, `Code`, `IssType`, `Category`, `CNumber`, `CDesc`, `ColCode`, `LLike`, `LifeS`, `PropS`, `BusS` FROM lu_racodes_temp ON DUPLICATE KEY UPDATE `ATID`= VALUES(`ATID`), `Code`= VALUES(`Code`), `IssType`= VALUES(`IssType`), `Category`= VALUES(`Category`), `CNumber`= VALUES(`CNumber`), `CDesc`= VALUES(`CDesc`), `ColCode`= VALUES(`ColCode`), `LLike`= VALUES(`LLike`), `LifeS`= VALUES(`LifeS`), `PropS`= VALUES(`PropS`), `BusS`= VALUES(`BusS`);
END
$$
DELIMITER ;
my table structure is like itemcode, size , sleeve ,item .so people inserting data like 'S0001','F','96' at the time of inserting i need to insert item field data like 'S0001-f-96' how do i write a trigger .
create TRIGGER [dbo].[name] ON [dbo].[table]
for INSERT
AS
declare #Itemcode varchar(30);
declare #Itemname varchar(40);
declare #Slv varchar(1);
declare #Createdate datetime;
declare #audit_action varchar(100);
select #Itemcode=i.ItemCode from inserted i;
select #Itemname=i.ItemName from inserted i;
select #Slv =i.U_SLV from inserted i;
select #Createdate =i.Createdate from inserted i;
set #audit_action='Inserted Record -- After Insert Trigger.';
update OITM_CLONE set sapitem =#Itemcode+'-'+#Slv where itemcode=#Itemcode and u_slv=#Slv and Createdate=#Createdate;
PRINT 'AFTER INSERT trigger fired.'
is this right?
I have one complex stored procedure that returns some rows with some calculated values
SELECT CalculatedField1 ,
CalculatedField2 ,
...
FROM ...
WHERE CONDITION
this sproc (lets call it procA) returns variable number of rows, depending on the WHERE condition. This works fine. What I need to do now is to write a stored procedure that will get the summary of these returned rows.
-- procB
SELECT SUM(CalculatedField1),
SELECT SUM(CalculatedField2),
...
FROM (EXEC procA params)
Is this possible?
Edit: creating a temp table did the job, however I have problems with passing output pareters.
CREATE PROCEDURE [dbo].[sprocB] (#prm INT = NULL OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
SET #prm = 1
SELECT Id FROM dbo.AnyTable
END
CREATE PROCEDURE [dbo].[sprocA] (#prm INT = NULL OUTPUT)
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #temp (Id INT)
INSERT INTO #temp
EXEC sprocB #prm
SELECT Id FROM #temp
END
To execute:
USE [MyDatabase]
GO
DECLARE #return_value int,
#prm int
EXEC #return_value = [dbo].[sprocA]
#prm = #prm OUTPUT
SELECT #prm as N'#prm'
SELECT 'Return Value' = #return_value
GO
The results from temp table are ok, resultset is retrieved correctly, however #pem value is still NULL.
It is possible but you need an auxiliary table:
CREATE PROCEDURE procB
AS
declare #table table (CalculatedField1 int, CalculatedField12 int)
insert into #table
EXEC sp_a
select SUM(CalculatedField1), SUM(CalculatedField2)
from #table
GO
This might do what you want:
create table #scratch (CalculatedField1 int, CalculatedField2 int,...)
insert into #scratch (exec procA params)
select sum(CalculatedField1), sum(CalculatedField2),... from #scratch
drop table #scratch
Am new to Stored procedures.I wrote the stored procedure to copy table from one dtabase to another database.On executing my stored procedures everytime My datas are added in the destination table .My row counts was increasing on every execution.
Please help to resolve the issue.Hope the problem In the loops.
My SP is:
--exec mall
alter procedure mall
as
begin
declare #mallid int
declare #mallname nvarchar(40)
declare #mallstatus nvarchar(40)
declare #malludsuomid nchar(2)
declare #malludsassetcode nvarchar(6)
declare #malludsassettype nvarchar(15)
declare #malludsremarks nvarchar(max)
declare #malludsdwdb int
declare #mallsecterr int
declare #mallassetid int
declare #secterr int
declare #Maxmallid int
declare #mallentityid int
Select #mallentityid = customtable.Bord_TableId From CRM.dbo.Custom_Tables as customtable With (NoLock) Where Upper(Bord_Caption) = Upper('Mall') And Bord_Deleted Is Null
DECLARE cur_address CURSOR FOR
SELECT
udsasset.Asset_ID,udsasset.Asset_Name,udsasset.Asset_Status,udsasset.UOM_ID, udsasset.Asset_Code,udsasset.Asset_Type,udsasset.Remarks,udsasset.DW_Key_Source_DB --,crmterr.TPro_SecTerr
from
CMA_UDS.dbo.Dim_Asset as udsasset
OPEN cur_address
FETCH NEXT FROM cur_address INTO #mallid,#mallname,#mallstatus,#malludsuomid,#malludsassetcode,#malludsassettype,#malludsremarks,#malludsdwdb --,#mallsecterr
WHILE ##FETCH_STATUS = 0
BEGIN
if not exists (select crmmall.mall_MallID from CRM.dbo.Mall as crmmall where crmmall.mall_MallID = #mallid)
begin
exec #Maxmallid = CRM.dbo.crm_next_id #Table_Id=#mallentityid
insert into
CRM.dbo.Mall
(mall_MallID,mall_Name,mall_Status,mall_uds_UOMID,mall_uds_asset_code,mall_uds_asset_type,
mall_uds_remarks,mall_uds_dw_db,mall_CreatedBy,mall_CreatedDate,mall_Secterr,mall_AMOSUploaded,mall_asset_id)
values(#Maxmallid,#mallname,#mallstatus,#malludsuomid,#malludsassetcode,#malludsassettype,#malludsremarks,#malludsdwdb,1,GETDATE(),
#mallsecterr,GETDATE(),#mallid)
end
else
begin
update
CRM.dbo.Mall
set
mall_asset_id=#mallid,mall_Name = #mallname,mall_Status=#mallstatus,mall_uds_UOMID =#malludsuomid,mall_uds_asset_code=#malludsassetcode,
mall_uds_asset_type=#malludsassettype,mall_uds_remarks=#malludsremarks,mall_uds_dw_db=#malludsdwdb,mall_UpdatedBy=1,
mall_UpdatedDate=GETDATE(),mall_Secterr=#mallsecterr,mall_AMOSUploaded=GETDATE()
where
mall_MallID=#mallid
end
FETCH NEXT FROM cur_address INTO #mallid,#mallname,#mallstatus,#malludsuomid,#malludsassetcode,#malludsassettype,#malludsremarks,#malludsdwdb--,#mallsecterr
end
CLOSE cur_address
DEALLOCATE cur_address
End
Why are you inserting crm_next_id as the value in mall_MallID, but using that same id to compare with #mallid to see if the record is already inserted? For example, if you have id 5, and you insert a new record with id 150, it's not going to see that the record is already inserted when you run the SP again. Next run, it will add record with id 151, then 152, and so forth forever. You shouldn't use the same field as both an auto-increment identity and a foreign key reference at the same time...
You either need to use the same #mallid when you insert the new records so they match, or after you generate a new id and insert into the table, update the original record CMA_UDS.dbo.Dim_Asset to have Asset_ID = #mallid so they are linked up properly. Which method you use depends on the meanings of those id's and what constraints you have in your particular application.