Optimize the procedure in Informix - sql

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;

Related

Validate Chilean RUT in a SQL database

I found this code at this website and is working well in SQL SERVER
CREATE FUNCTION [dbo].[CalculaDigitoRut]
(
#rut int
)
RETURNS char(1)
AS
BEGIN
DECLARE #digito int
DECLARE #contador int
DECLARE #multiplo int
DECLARE #acumulador int
DECLARE #ret char
set #contador = 2
set #acumulador = 0
while (#rut <> 0)
begin
set #multiplo = (#Rut % 10) * #contador
set #acumulador = #acumulador + #multiplo
set #rut = #rut / 10
set #contador = #contador + 1
if (#contador = 8)
set #contador = 2
end
set #digito = 11 - (#acumulador % 11)
if (#digito = 10)
return ('K')
if (#digito = 11)
return ('0')
return (#digito)
END
Expected result
RUT -- validation_digit
10214564 K
3781561 6
3433444 7
3066256 3
I tried to adapt it to the MariaDB (10.3.30-MariaDB) syntax and after a few tries there weren't syntax erros but the function isn't returning the expected result.
Heres the new code for MariaDB
CREATE FUNCTION Calculate_national_id_verifier (rut INT)
RETURNS CHAR(1)
BEGIN
DECLARE digito INT;
DECLARE contador INT;
DECLARE multiplo INT;
DECLARE acumulador INT;
DECLARE ret CHAR;
SET contador = 2;
SET acumulador = 0;
WHILE rut <> 0 DO
SET multiplo = (rut % 10) * contador;
SET acumulador = acumulador + multiplo;
SET rut = rut / 10;
SET contador = contador + 1; -- 3
IF (contador = 8) THEN
SET contador = 2;
END IF;
END WHILE;
SET digito = 11 - (acumulador % 11);
IF (digito = 10) THEN
RETURN ('K');
ELSEIF (digito = 11) THEN
RETURN ('0');
ELSE
RETURN (digito);
END IF;
END;
This problem seems very dumb, I've been comparing it for hours and I can't find where is the problem and why there is a difference between both functions.
I'm using DBeaver 21.3.5 as a client to run the queries.
Here are the actual results
RUT -- validation_digit
10214564 6
3781561 K
3433444 7
3066256 5
This is my firts time asking something so sorry if I made a mistake. I couldn't find the answer.

How to compare two strings based on percent match in SQL

I want to post a solution to a interesting problem I was facing in T-SQL.
The problem:
Compare two string fields based on a percent match.
In addition, the two strings may have the words in them translocated.
For example: "Joni Bravo" and "Bravo Joni". These two strings should return a match of 100%, which means that position is not relevant. Few more things worth noting are that this code is made to compare strings that have space as delimiter in them. If the first string doesnt have space the match is set to 100% without actual check. This was not developed, because the strings this function is ment to compare always contain two or more words. Also, it is written on MS SQL Server 2017 if that mathers.
So here is the solution, hope this helps anyone :)
gl
/****** Object: UserDefinedFunction [dbo].[STRCOMP] Script Date: 29/03/2018 15:31:45 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[STRCOMP] (
-- Add the parameters for the function here
#name_1 varchar(255),#name_2 varchar(255)
)
RETURNS float
AS
BEGIN
-- Declare the return variable and any needed variable here
declare #p int = 0;
declare #c int = 0;
declare #br int = 0;
declare #p_temp int = 0;
declare #emergency_stop int = 0;
declare #fixer int = 0;
declare #table1_temp table (
row_id int identity(1,1),
str1 varchar (255));
declare #table2_temp table (
row_Id int identity(1,1),
str2 varchar (255));
declare #n int = 1;
declare #count int = 1;
declare #result int = 0;
declare #total_result float = 0;
declare #result_temp int = 0;
declare #variable float = 0.0;
--clean the two strings from unwanted symbols and numbers
set #name_1 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#name_1,'!',''),' ',' '),'1',''),'2',''),'3',''),'4',''),'5',''),'0',''),'6',''),'7',''),'8',''),'9','');
set #name_2 = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(#name_2,'!',''),' ',' '),'1',''),'2',''),'3',''),'4',''),'5',''),'0',''),'6',''),'7',''),'8',''),'9','');
--check if the first string has more than one words inside. If the string does
--not have more than one words, return 100%
set #c = charindex(' ',substring(#name_1,#p,len(#name_1)));
IF(#c = 0)
BEGIN
RETURN 100.00
END;
--main logic of the operation. This is based on sound indexing and comparing the
--outcome. This loops through the string whole words and determines their soundex
--code and then compares it one against the other to produce a definitive number --showing the raw match between the two strings #name_1 and #name_2.
WHILE (#br != 2 or #emergency_stop = 20)
BEGIN
insert into #table1_temp(str1)
select substring (#name_1,#p,#c);
set #p = len(substring (#name_1,#p,#c))+2;
set #p = #p + #p_temp - #fixer;
set #p_temp = #p;
set #c = CASE WHEN charindex(' ',substring(#name_1,#p,len(#name_1))) = 0 THEN len(#name_1) ELSE charindex(' ',substring(#name_1,#p,len(#name_1))) END;
set #fixer = 1;
set #br = CASE WHEN charindex(' ',substring(#name_1,#p,len(#name_1))) = 0 THEN #br + 1 ELSE 0 END;
set #emergency_stop = #emergency_stop +1;
END;
set #p = 0;
set #br = 0;
set #emergency_stop = 0;
set #fixer = 0;
set #p_temp = 0;
set #c = charindex(' ',substring(#name_2,#p,len(#name_2)));
WHILE (#br != 2 or #emergency_stop = 20)
BEGIN
insert into #table2_temp(str2)
select substring (#name_2,#p,#c);
set #p = len(substring (#name_2,#p,#c))+2;
set #p = #p + #p_temp - #fixer;
set #p_temp = #p;
set #c = CASE WHEN charindex(' ',substring(#name_2,#p,len(#name_2))) = 0 THEN len(#name_2) ELSE charindex(' ',substring(#name_2,#p,len(#name_2))) END;
set #fixer = 1;
set #br = CASE WHEN charindex(' ',substring(#name_2,#p,len(#name_2))) = 0 THEN #br + 1 ELSE 0 END;
set #emergency_stop = #emergency_stop +1;
END;
WHILE((select str1 from #table1_temp where row_id = #n) is not null)
BEGIN
set #count = 1;
set #result = 0;
WHILE((select str2 from #table2_temp where row_id = #count) is not null)
BEGIN
set #result_temp = DIFFERENCE((select str1 from #table1_temp where row_id = #n),(select str2 from #table2_temp where row_id = #count));
IF(#result_temp > #result)
BEGIN
set #result = #result_temp;
END;
set #count = #count + 1;
END;
set #total_result = #total_result + #result;
set #n = #n + 1;
END;
--gather the results and transform them in a percent match.
set #variable = (select #total_result / (select max(row_count) from (
select max(row_id) as row_count from #table1_temp
union
select max(row_id) as row_count from #table2_temp) a));
RETURN #variable/4 * 100;
END
GO
PS: I decided to write it in a user-defined function just for the needs of my project.

SQL Server 2008 - insert trigger not firing

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!

using of functions or views in sql

I have made functions and views in SQL server. I excuted them and they are successfuly stored.
Now what should I write to use these views or functions in another query?!
I have tried
select something
from FunctionName;
but system doesn't recongnize the function.
the function is:
create function TableOfDecades ()
returns #functiontable table
(
decadeBegin int,
decadeEnd int,
NumOfMovies int
)
as
begin
declare #movie1 int;
declare #movie2 int;
declare #movie3 int;
declare #movie4 int;
declare #movie5 int;
declare #year1 int;
declare #year2 int;
select #movie1 = count(id)
from MOVIE
where year >=1350 and year <1360;
select #movie2 = count(id)
from MOVIE
where year >=1360 and year <1370;
select #movie3 = count(id)
from MOVIE
where year >=1370 and year <1380;
select #movie4 = count(id)
from MOVIE
where year >=1380 and year <1390;
select #movie5 = count(id)
from MOVIE
where year >=1390 and year <1400;
declare #maxOfMovies int;
set #maxOfMovies = -1;
if( #movie1 > #maxOfMovies )
begin
set #maxOfMovies = #movie1;
set #year1 = 1350;
set #year2 = 1360;
end
if( #movie2 > #maxOfMovies )
begin
set #maxOfMovies = #movie2;
set #year1 = 1360;
set #year2 = 1370;
end
if( #movie3 > #maxOfMovies )
begin
set #maxOfMovies = #movie3;
set #year1 = 1370;
set #year2 = 1380;
end
if( #movie4 > #maxOfMovies )
begin
set #maxOfMovies = #movie4;
set #year1 = 1380;
set #year2 = 1390;
end
if( #movie5 > #maxOfMovies )
begin
set #maxOfMovies = #movie5;
set #year1 = 1390;
set #year2 = 1400;
end
insert into #functiontable
select #maxOfMovies, #year1, #year2;
RETURN;
end
that I excuted it and it saved in folder programmability->functions->table-valued functions
Following should work ..
SELECT decadeBegin, decadeEnd, NumOfMovies
FROM dbo.TableOfDecades();
Your function needs to specifically return a Table type before it can be used by another sql call.
see http://technet.microsoft.com/en-us/library/ms191165%28v=sql.105%29.aspx
different implementations of SQL have different formats for referring to the Table-Valued Functions..

An object or column name is missing or empty

I am getting the following error
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
for the query show below:
CREATE PROC [dbo].[Sp_Table1] #ctlg_ipt_event_id int
AS
SET NOCOUNT ON
DECLARE #current_status NCHAR(1), #ready_status_code NCHAR(1)
DECLARE #current_action NCHAR(1), #ready_action_code NCHAR(1), #done_action_code NCHAR(1)
DECLARE #pst_user_id int
SELECT #current_status = status_code
,#current_action = action_code
,#pst_user_id = last_mod_user_id
FROM merch_ctlg_ipt_event
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
Select #ready_status_code = 'o'
, #ready_action_code = 'a'
, #done_action_code = 'b'
IF #current_status <> #ready_status_code OR #current_action <> #ready_action_code
BEGIN
RETURN
END
BEGIN TRAN
declare #rows int
,#err int
,#i int
,#name nvarchar(50) --COLLATE SQL_AltDiction_Pref_CP850_CI_AS
,#resolved_View_Name_category_id int
,#xref_value int
,#availability_start_date datetime
,#availability_end_date datetime
,#status_code int
,#last_mod_user_id int
,#CT datetime
,#supplier_id int
,#View_Name_id int
select #i = 1
,#CT = current_timestamp
Select Distinct mc.name,
mc.resolved_View_Name_category_id,
mc.xref_value,
mc.availability_start_date,
mc.availability_end_date,
mc.status_code,
CASE WHEN mc.last_mod_user_id = 42
THEN #pst_user_id
ELSE mc.last_mod_user_id
END as last_mod_user_id,
CURRENT_tsp
,IDENTITY(int,1,1) as rn
,si.supplier_id
,si.View_Name_id
into #temp
FROM View_Name AS si
JOIN merch_ctlg_ipt_View_Name AS mc
ON mc.supplier_id = si.supplier_id
AND mc.resolved_View_Name_id = si.View_Name_id
AND mc.cat_imp_event_id = #ctlg_ipt_event_id
AND mc.accept_flag = 'y'
WHERE si.shipper_flag = 'n'
select #rows=##ROWCOUNT,#err=##error
if #rows > 0 and #err=0
Begin
While #i <=#rows
begin
SElect #name = name,
#resolved_View_Name_category_id = resolved_View_Name_category_id,
#xref_value = xref_value,
#availability_start_date = availability_start_date,
#availability_end_date = availability_end_date,
#status_code = mc.status_code,
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
,#supplier_id=supplier_id
,#View_Name_id=View_Name_id
from #temp
Where rn=#i
UPDATE View_Name
SET name = #name,
View_Name_category_id = #resolved_View_Name_category_id,
xref_value = #xref_value,
availability_start_date = #availability_start_date,
availability_end_date = #availability_end_date,
status_code = #status_code,
last_mod_user_id = #last_mod_user_id ,
last_mod_timestamp = #CT
Where #sup_id = supplier_id
AND #View_Name_id = View_Name_id
AND shipper_flag = 'n'
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
End
End
UPDATE
merch_ctlg_ipt_event
SET action_code = #done_action_code,
last_mod_timestamp = #CT
WHERE ctlg_ipt_event_id = #ctlg_ipt_event_id
IF ##ERROR > 0
BEGIN
ROLLBACK TRAN
RETURN
END
COMMIT TRAN
Return
go
Could you please help ?
You have 2 commas in a row here
#last_mod_user_id =last_mod_user_id ,
,#i=#i+1
Also probably not relevant to the error message but you have a line
Where #sup_id = supplier_id
but the declared variable is #supplier_id