Remove Accents DB2 - sql

Does someone knows how to get rid of accents words in DB2 ?
I got that one bellow :
select UPPER( 'test' || 'DescricaoDomino' || NVL('SiglaDomino', 'X')) from tbProcTeste ;
And i got that result :
1
-------------------------------
TESTDESCRICAODOMINOSIGLADOMINO
However i could receive a string with accents like this one "!":
select UPPER( 'test!' || 'DescricaoDomino' || NVL('SiglaDomino', 'X'))
from tbProcTeste ;
And id like to get a same result above .
Someone knows how do i do that ?
Result that i expected
1
TESTDESCRICAODOMINOSIGLADOMINO
I dont have huge DB2 background .
DB2 Version 11,1
Sincerly

Based on the mapping in this post https://stackoverflow.com/a/9667817/9525344
the following Db2 function will replace most(?) of the possible Unicode characters with diacritic marks with their simple Latin equivalent (which may, or may not be what is actually used as a replacement in a given language. E..g in German, ü is usually replaced with ue, not u)
CREATE OR REPLACE FUNCTION DB_STRIP_DIACRITICS(string VARCHAR(32000))
RETURNS VARCHAR(32000)
LANGUAGE SQL CONTAINS SQL DETERMINISTIC NO EXTERNAL ACTION
RETURN
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
string,
'[ÁĂẮẶẰẲẴǍÂẤẬẦẨẪÄǞȦǠẠȀÀẢȂĀĄÅǺḀȺÃⱯᴀ]', 'A'),
'[Ꜳ]', 'AA'),
'[ÆǼǢᴁ]', 'AE'),
'[Ꜵ]', 'AO'),
'[Ꜷ]', 'AU'),
'[ꜸꜺ]', 'AV'),
'[Ꜽ]', 'AY'),
'[ḂḄƁḆɃƂʙᴃ]', 'B'),
'[ĆČÇḈĈĊƇȻꜾᴄ]', 'C'),
'[ĎḐḒḊḌƊḎDzDžĐƋꝹᴅ]', 'D'),
'[DZDŽ]', 'DZ'),
'[ÉĔĚȨḜÊẾỆỀỂỄḘËĖẸȄÈẺȆĒḖḔĘɆẼḚƐƎᴇⱻ]', 'E'),
'[Ꝫ]', 'ET'),
'[ḞƑꝻꜰ]', 'F'),
'[ǴĞǦĢĜĠƓḠǤꝽɢʛ]', 'G'),
'[ḪȞḨĤⱧḦḢḤĦʜ]', 'H'),
'[ÍĬǏÎÏḮİỊȈÌỈȊĪĮƗĨḬɪ]', 'I'),
'[IJ]', 'IJ'),
'[Ꝭ]', 'IS'),
'[ĴɈᴊ]', 'J'),
'[ḰǨĶⱩꝂḲƘḴꝀꝄᴋ]', 'K'),
'[ĹȽĽĻḼḶḸⱠꝈḺĿⱢLjŁꞀʟᴌ]', 'L'),
'[LJ]', 'LJ'),
'[ḾṀṂⱮƜᴍ]', 'M'),
'[ŃŇŅṊṄṆǸƝṈȠNjÑɴᴎ]', 'N'),
'[NJ]', 'NJ'),
'[ÓŎǑÔỐỘỒỔỖÖȪȮȰỌŐȌÒỎƠỚỢỜỞỠȎꝊꝌŌṒṐƟǪǬØǾÕṌṎȬƆᴏᴐ]', 'O'),
'[Œɶ]', 'OE'),
'[Ƣ]', 'OI'),
'[Ꝏ]', 'OO'),
'[Ȣᴕ]', 'OU'),
'[ṔṖꝒƤꝔⱣꝐᴘ]', 'P'),
'[ꝘꝖ]', 'Q'),
'[ꞂŔŘŖṘṚṜȐȒṞɌⱤʁʀᴙᴚ]', 'R'),
'[ꞄŚṤŠṦŞŜȘṠṢṨꜱ]', 'S'),
'[ꞆŤŢṰȚȾṪṬƬṮƮŦᴛ]', 'T'),
'[Ꜩ]', 'TZ'),
'[ÚŬǓÛṶÜǗǙǛǕṲỤŰȔÙỦƯỨỰỪỬỮȖŪṺŲŮŨṸṴᴜ]', 'U'),
'[ɅꝞṾƲṼᴠ]', 'V'),
'[Ꝡ]', 'VY'),
'[ẂŴẄẆẈẀⱲᴡ]', 'W'),
'[ẌẊ]', 'X'),
'[ÝŶŸẎỴỲƳỶỾȲɎỸʏ]', 'Y'),
'[ŹŽẐⱫŻẒȤẔƵᴢ]', 'Z'),
'[áăắặằẳẵǎâấậầẩẫäǟȧǡạȁàảȃāąᶏẚåǻḁⱥãɐₐ]', 'a'),
'[ꜳ]', 'aa'),
'[æǽǣᴂ]', 'ae'),
'[ꜵ]', 'ao'),
'[ꜷ]', 'au'),
'[ꜹꜻ]', 'av'),
'[ꜽ]', 'ay'),
'[ḃḅɓḇᵬᶀƀƃ]', 'b'),
'[ćčçḉĉɕċƈȼↄꜿ]', 'c'),
'[ďḑḓȡḋḍɗᶑḏᵭᶁđɖƌꝺ]', 'd'),
'[dzdž]', 'dz'),
'[éĕěȩḝêếệềểễḙëėẹȅèẻȇēḗḕⱸęᶒɇẽḛɛᶓɘǝₑ]', 'e'),
'[ꝫ]', 'et'),
'[ḟƒᵮᶂꝼ]', 'f'),
'[ff]', 'ff'),
'[ffi]', 'ffi'),
'[ffl]', 'ffl'),
'[fi]', 'fi'),
'[fl]', 'fl'),
'[ǵğǧģĝġɠḡᶃǥᵹɡᵷ]', 'g'),
'[ḫȟḩĥⱨḧḣḥɦẖħɥʮʯ]', 'h'),
'[ƕ]', 'hv'),
'[ıíĭǐîïḯịȉìỉȋīįᶖɨĩḭᴉᵢ]', 'i'),
'[ij]', 'ij'),
'[ꝭ]', 'is'),
'[ȷɟʄǰĵʝɉⱼ]', 'j'),
'[ḱǩķⱪꝃḳƙḵᶄꝁꝅʞ]', 'k'),
'[ĺƚɬľļḽȴḷḹⱡꝉḻŀɫᶅɭłꞁ]', 'l'),
'[lj]', 'lj'),
'[ḿṁṃɱᵯᶆɯɰ]', 'm'),
'[ńňņṋȵṅṇǹɲṉƞᵰᶇɳñ]', 'n'),
'[nj]', 'nj'),
'[ɵóŏǒôốộồổỗöȫȯȱọőȍòỏơớợờởỡȏꝋꝍⱺōṓṑǫǭøǿõṍṏȭɔᶗᴑᴓₒ]', 'o'),
'[ᴔœ]', 'oe'),
'[ƣ]', 'oi'),
'[ꝏ]', 'oo'),
'[ȣ]', 'ou'),
'[ṕṗꝓƥᵱᶈꝕᵽꝑ]', 'p'),
'[ꝙʠɋꝗ]', 'q'),
'[ꞃŕřŗṙṛṝȑɾᵳȓṟɼᵲᶉɍɽɿɹɻɺⱹᵣ]', 'r'),
'[ꞅſẜẛẝśṥšṧşŝșṡṣṩʂᵴᶊȿ]', 's'),
'[st]', 'st'),
'[ꞇťţṱțȶẗⱦṫṭƭṯᵵƫʈŧʇ]', 't'),
'[ᵺ]', 'th'),
'[ꜩ]', 'tz'),
'[ᴝúŭǔûṷüǘǚǜǖṳụűȕùủưứựừửữȗūṻųᶙůũṹṵᵤ]', 'u'),
'[ᵫ]', 'ue'),
'[ꝸ]', 'um'),
'[ʌⱴꝟṿʋᶌⱱṽᵥ]', 'v'),
'[ꝡ]', 'vy'),
'[ʍẃŵẅẇẉẁⱳẘ]', 'w'),
'[ẍẋᶍₓ]', 'x'),
'[ʎýŷÿẏỵỳƴỷỿȳẙɏỹ]', 'y'),
'[źžẑʑⱬżẓȥẕᵶᶎʐƶɀ]', 'z')

We solved this with a Java class implementing the replace with a Pattern
/opt/ibm/db2/V10.5_WSE/java/jdk64/bin/javac GdprNameRegexp.java
Packaging it in a jar
/opt/ibm/db2/V10.5_WSE/java/jdk64/bin/jar cvf GdprNameRegexp.jar GdprNameRegexp.class
And loading it in db2 as source for a UDF
CALL sqlj.install_jar('file:/home/db2inst1/GdprNameRegexp.jar', 'GDPRNAME')
CREATE FUNCTION GDPRNAME_VERIFY(WORD VARCHAR(255)) RETURNS INTEGER FENCED EXTERNAL NAME 'GDPRNAME:GdprNameRegexp.nameFieldsPattern' NOT VARIANT NO SQL PARAMETER STYLE java LANGUAGE java NO EXTERNAL ACTION
CREATE FUNCTION GDPRNAME_REPLACE(WORD VARCHAR(255), REPLACEMENT VARCHAR(255)) RETURNS VARCHAR(255) FENCED EXTERNAL NAME 'GDPRNAME:GdprNameRegexp.replaceNameFieldPattern' NOT VARIANT NO SQL PARAMETER STYLE java LANGUAGE java NO EXTERNAL ACTION
Java class example:
import java.util.regex.Pattern;
import java.text.Normalizer;
public class GdprNameRegexp {
private static Pattern CONSECUTIVE_CHAR_PATTERN = Pattern.compile("(.)\\1\\1\\1+", Pattern.CASE_INSENSITIVE);
private static Pattern SPECIAL_CHARS_PATTERN = Pattern.compile("[^\\p{L}\\'\\- - [\u00BA,\u00AA,\u02BA]]", Pattern.CASE_INSENSITIVE);
private static Pattern CONTAINS_NUMBERS_PATTERN = Pattern.compile(".*\\d+.*", Pattern.CASE_INSENSITIVE);
public static int nameFieldsPattern(String word) {
int rsp = 0;
if (word != null && !"".equals(word.trim())) {
word = Normalizer.normalize(word, Normalizer.Form.NFC);
if (SPECIAL_CHARS_PATTERN.matcher(word).find()) {
rsp += -2;
}
if (CONSECUTIVE_CHAR_PATTERN.matcher(word).find()) {
rsp += -1;
}
if (CONTAINS_NUMBERS_PATTERN.matcher(word).find()) {
rsp += -4;
}
if (rsp == 0) {
rsp = 1;
}
}
return rsp;
}
public static String replaceNameFieldPattern(String word, String replacement) {
if (word != null) {
if (!"".equals(word.trim()) && replacement != null) {
word = Normalizer.normalize(word, Normalizer.Form.NFC);
String result = SPECIAL_CHARS_PATTERN.matcher(word).replaceAll(replacement).trim();
if (!"".equals(replacement)) {
int stop = 10;
result.replaceAll(replacement + replacement, replacement);
while (stop > 0 && result.contains(replacement + replacement)) {
result.replaceAll(replacement + replacement, replacement);
stop--;
}
}
return result.trim();
}
return word.trim();
}
return "";
}
}

ive been looking forward to solve that problem and i found that one bellow :
CREATE OR REPLACE FUNCTION ReplaceFunction(
IN pe_sTexto VARCHAR(8000)
) RETURNS VARCHAR(8000)
BEGIN
SET pe_sTexto = REPLACE (pe_sTexto,'É', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'œ', 'oe');
SET pe_sTexto = REPLACE (pe_sTexto,'æ', 'ae');
SET pe_sTexto = REPLACE (pe_sTexto,'Á', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'Ç', 'C');
SET pe_sTexto = REPLACE (pe_sTexto,'É', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'Í', 'I');
SET pe_sTexto = REPLACE (pe_sTexto,'Ó', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'Ú', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'À', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'È', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'Ì', 'I');
SET pe_sTexto = REPLACE (pe_sTexto,'Ò', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'Ù', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'Â', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'Ê', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'Ô', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'Û', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'Ã', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'Õ', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'Ë', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'Ü', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'é', 'e');
SET pe_sTexto = REPLACE (pe_sTexto,'œ', 'oe');
SET pe_sTexto = REPLACE (pe_sTexto,'æ', 'ae');
SET pe_sTexto = REPLACE (pe_sTexto,'á', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'ç', 'C');
SET pe_sTexto = REPLACE (pe_sTexto,'é', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'í', 'I');
SET pe_sTexto = REPLACE (pe_sTexto,'ó', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'ú', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'à', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'à', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'ì', 'I');
SET pe_sTexto = REPLACE (pe_sTexto,'ò', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'ù', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'ã', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'ê', 'E');
SET pe_sTexto = REPLACE (pe_sTexto,'ô', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'û', 'U');
SET pe_sTexto = REPLACE (pe_sTexto,'ã', 'A');
SET pe_sTexto = REPLACE (pe_sTexto,'õ', 'O');
SET pe_sTexto = REPLACE (pe_sTexto,'!', '');
SET pe_sTexto = REPLACE (pe_sTexto,'.', '');
SET pe_sTexto = REPLACE (pe_sTexto,'*', '');
SET pe_sTexto = REPLACE (pe_sTexto,'#', '');
SET pe_sTexto = REPLACE (pe_sTexto,'#', '');
SET pe_sTexto = REPLACE (pe_sTexto,'$', '');
SET pe_sTexto = REPLACE (pe_sTexto,'&', '');
SET pe_sTexto = REPLACE (pe_sTexto,'-', '');
SET pe_sTexto = REPLACE (pe_sTexto,'+', '');
SET pe_sTexto = REPLACE (pe_sTexto,',', '');
SET pe_sTexto = REPLACE (pe_sTexto,')', '');
SET pe_sTexto = REPLACE (pe_sTexto,'(', '');
SET pe_sTexto = REPLACE (pe_sTexto,':', '');
SET pe_sTexto = REPLACE (pe_sTexto,'[', '');
SET pe_sTexto = REPLACE (pe_sTexto,']', '');
SET pe_sTexto = REPLACE (pe_sTexto,'>', '');
SET pe_sTexto = REPLACE (pe_sTexto,'<', '');
SET pe_sTexto = REPLACE (pe_sTexto,'"', '');
SET pe_sTexto = REPLACE (pe_sTexto,'´', '');
SET pe_sTexto = REPLACE (pe_sTexto,'~', '');
RETURN pe_sTexto;
END #
I know its big , but it works for me !
Thanks anyway !

For DB2 you can use
CREATE OR REPLACE FUNCTION Z_REMOVEACCENTS( p_Str nvarchar2 )
RETURN nvarchar2
AS
BEGIN
p_Str := REPLACE(p_Str, 'É', 'E');
p_Str := REPLACE(p_Str, 'œ', 'oe');
p_Str := REPLACE(p_Str, 'æ', 'ae');
p_Str := REPLACE(p_Str, 'Á', 'A');
p_Str := REPLACE(p_Str, 'Ç', 'C');
p_Str := REPLACE(p_Str, 'É', 'E');
p_Str := REPLACE(p_Str, 'Í', 'I');
p_Str := REPLACE(p_Str, 'Ó', 'O');
p_Str := REPLACE(p_Str, 'Ú', 'U');
p_Str := REPLACE(p_Str, 'À', 'A');
p_Str := REPLACE(p_Str, 'È', 'E');
p_Str := REPLACE(p_Str, 'Ì', 'I');
p_Str := REPLACE(p_Str, 'Ò', 'O');
p_Str := REPLACE(p_Str, 'Ù', 'U');
p_Str := REPLACE(p_Str, 'Â', 'A');
p_Str := REPLACE(p_Str, 'Ê', 'E');
p_Str := REPLACE(p_Str, 'Ô', 'O');
p_Str := REPLACE(p_Str, 'Û', 'U');
p_Str := REPLACE(p_Str, 'Ã', 'A');
p_Str := REPLACE(p_Str, 'Õ', 'O');
p_Str := REPLACE(p_Str, 'Ë', 'E');
p_Str := REPLACE(p_Str, 'Ü', 'U');
p_Str := REPLACE(p_Str, 'é', 'e');
p_Str := REPLACE(p_Str, 'œ', 'oe');
p_Str := REPLACE(p_Str, 'æ', 'ae');
p_Str := REPLACE(p_Str, 'á', 'A');
p_Str := REPLACE(p_Str, 'ç', 'C');
p_Str := REPLACE(p_Str, 'é', 'E');
p_Str := REPLACE(p_Str, 'í', 'I');
p_Str := REPLACE(p_Str, 'ó', 'O');
p_Str := REPLACE(p_Str, 'ú', 'U');
p_Str := REPLACE(p_Str, 'à', 'A');
p_Str := REPLACE(p_Str, 'à', 'E');
p_Str := REPLACE(p_Str, 'ì', 'I');
p_Str := REPLACE(p_Str, 'ò', 'O');
p_Str := REPLACE(p_Str, 'ù', 'U');
p_Str := REPLACE(p_Str, 'ã', 'A');
p_Str := REPLACE(p_Str, 'ê', 'E');
p_Str := REPLACE(p_Str, 'ô', 'O');
p_Str := REPLACE(p_Str, 'û', 'U');
p_Str := REPLACE(p_Str, 'ã', 'A');
p_Str := REPLACE(p_Str, 'õ', 'O');
RETURN p_Str;
END;

Something like this would be shorter (and faster) than the other answers
CREATE OR REPLACE FUNCTION STRIP_ACCENTS(S VARCHAR(32000))
RETURNS VARCHAR(32000)
LANGUAGE SQL CONTAINS SQL DETERMINISTIC NO EXTERNAL ACTION
RETURN
REPLACE(REPLACE(TRANSLATE(GRAPHIC(s)
,'ACEIOUAEIOUAEOUAOEUaceiouaaiouaeouao'
,'ÁÇÉÍÓÚÀÈÌÒÙÂÊÔÛÃÕËÜáçéíóúààìòùãêôûãõ'),'œ','oe'),'æ','ae')
Obviously, the above does not cover all accented characters in Unicode (it's not even a very good list to be honest), so feel free to extend it
Alternatively see my other answer for a more complete solution

Related

ORA-06502: PL/SQL: numeric or value error: character to number conversion error in package function

I am trying to create a function that returns pipelined table with input parameters being varchar2, date or number. I am trying to input amount as varchar2 because I can't process it like a number with comma before decimals. Here is body of my package function:
FUNCTION kreiraj_reprogram_rate (p_sifra_kupca VARCHAR2,
p_id_kartice_kupca NUMBER,
p_iznos_s_pdv VARCHAR2,
p_broj_rata NUMBER,
p_frekvencija_dospijeca NUMBER,
p_datum_dospijeca VARCHAR2,
p_datum_dokumenta VARCHAR2)
RETURN reprogram_rate_table
PIPELINED
IS
v_data reprogram_rate_rec;
v_user VARCHAR2 (200) := mc__secure_context.get_context_username ();
v_iznos_rate NUMBER;
v_broj_rate NUMBER;
v_zadnja_rata NUMBER;
v_datum_dokumenta DATE;
v_datum_dospijeca DATE;
BEGIN
write_log_table ('TEST','p_iznos_s_pdv: '|| to_number(p_iznos_s_pdv));
v_datum_dospijeca := TO_DATE (p_datum_dospijeca, 'dd.mm.yyyy');
v_datum_dokumenta := TO_DATE (p_datum_dokumenta, 'dd.mm.yyyy');
v_iznos_rate := ROUND (to_number(p_iznos_s_pdv) / p_broj_rata, 2);
v_zadnja_rata :=
p_iznos_s_pdv - ROUND ((p_broj_rata - 1) * v_iznos_rate, 2);
v_broj_rate := 1;
FOR r IN 1 .. p_broj_rata
LOOP
IF v_broj_rate = p_broj_rata
THEN
v_data.osnovica := ROUND ((v_zadnja_rata / 1.25), 2);
v_data.pdv := ROUND (v_zadnja_rata * 0.2, 2);
v_data.ukupno := v_zadnja_rata;
ELSE
v_data.osnovica := ROUND ((v_iznos_rate / 1.25), 2);
v_data.pdv := ROUND (v_iznos_rate * 0.2, 2);
v_data.ukupno := ROUND (v_iznos_rate, 2);
END IF;
v_data.sifra_kupca := p_sifra_kupca;
v_data.kartica_kupca := p_id_kartice_kupca;
v_data.broj_rate := v_broj_rate;
v_data.datum_dokumenta := v_datum_dokumenta;
v_data.datum_dospijeca := v_datum_dospijeca;
PIPE ROW (v_data);
v_broj_rate := v_broj_rate + 1;
v_datum_dospijeca :=
CASE
WHEN p_frekvencija_dospijeca = 1
THEN
ADD_MONTHS (v_datum_dospijeca, 1)
WHEN p_frekvencija_dospijeca = 3
THEN
ADD_MONTHS (v_datum_dospijeca, 3)
WHEN p_frekvencija_dospijeca = 6
THEN
ADD_MONTHS (v_datum_dospijeca, 6)
WHEN p_frekvencija_dospijeca = 12
THEN
ADD_MONTHS (v_datum_dospijeca, 12)
END;
END LOOP;
END kreiraj_reprogram_rate;
And the error says that error is on the first write_log_table line where I try to convert value 4159,57 to number.
I tried select to_number('4159,57') from dual in SQL developer and it works just fine so I can't figure out what is the catch.
Can someone help?
Thanks.

PL/SQL cursor that skip rows recording in database

I can`t understand why cursor that I have in my procedure
skip rows.
Here is my cursor:
OPEN c_denormalized_data FOR lv_sql_str;
LOOP
FETCH c_denormalized_data
INTO r_denormalized_data;
EXIT WHEN c_denormalized_data%NOTFOUND;
INSERT INTO bpdev.bp_real_to_fiskal_reference
(r_customer_trx_id,
r_trx_number,
r_trx_date,
r_amount,
r_amount_due_rem,
diff,
f_trx_number,
f_trx_date,
f_amount,
NULLS,
notnulls,
org_id,
data_loaded_for_days)
VALUES
(r_denormalized_data.r_customer_trx_id,
r_denormalized_data.r_trx_number,
r_denormalized_data.r_trx_date,
r_denormalized_data.r_amount,
r_denormalized_data.r_amount_due_rem,
r_denormalized_data.diff,
r_denormalized_data.f_trx_number,
r_denormalized_data.f_trx_date,
r_denormalized_data.f_amount,
r_denormalized_data.nulls,
r_denormalized_data.notnulls,
r_denormalized_data.org_id,
days_before_today);
COMMIT;
END LOOP;
lv_sql_str is dynamic SELECT the execution of which takes about 30 min.
The cursor is used because this select is dynamically generated based on the input parameters.
If I execute only a SELECT statement I receive all data that I expect, but when I execute procedure to insert in database I losе records
that appear in the data returned by my SELECT.
I can't understand why these records are skipped and are not inserted in the table.
Does anyone have an idea where my mistake is?
Here is my full code:
PROCEDURE load_denormalized_data(errbuf OUT NOCOPY VARCHAR2,
retcode OUT NOCOPY NUMBER,
days_before_today IN NUMBER,
real_legal_entyties_id_list IN VARCHAR2) IS
TYPE tc_denormalized_data IS REF CURSOR;
c_denormalized_data tc_denormalized_data;
TYPE tr_denormalized_data IS RECORD(
r_customer_trx_id bpdev.bp_real_to_fiskal_reference.r_customer_trx_id%TYPE,
r_trx_number bpdev.bp_real_to_fiskal_reference.r_trx_number%TYPE,
r_trx_date bpdev.bp_real_to_fiskal_reference.r_trx_date%TYPE,
r_amount bpdev.bp_real_to_fiskal_reference.r_amount%TYPE,
r_amount_due_rem bpdev.bp_real_to_fiskal_reference.r_amount_due_rem%TYPE,
diff bpdev.bp_real_to_fiskal_reference.diff%TYPE,
f_trx_number bpdev.bp_real_to_fiskal_reference.f_trx_number%TYPE,
f_trx_date bpdev.bp_real_to_fiskal_reference.f_trx_date%TYPE,
f_amount bpdev.bp_real_to_fiskal_reference.f_amount%TYPE,
NULLS bpdev.bp_real_to_fiskal_reference.nulls%TYPE,
notnulls bpdev.bp_real_to_fiskal_reference.notnulls%TYPE,
org_id bpdev.bp_real_to_fiskal_reference.org_id%TYPE);
r_denormalized_data tr_denormalized_data;
lv_where_le_ids VARCHAR2(3000);
lv_sql_str VARCHAR2(5000);
BEGIN
bpdev.bp_utils.put_log('>>>--------ПОТРЕБИТЕЛСКИ СЪОБЩЕНИЯ--------<<<');
bpdev.bp_utils.put_log('Изтриване на старите данни.');
DELETE bpdev.bp_real_to_fiskal_reference rfr;
COMMIT;
lv_where_le_ids := bp_utils.set_where_clause('invr.org_id',
real_legal_entyties_id_list,
',',
';',
0);
lv_sql_str :=
'SELECT invr.customer_trx_id r_customer_trx_id,
invr.trx_number r_trx_number,
invr.trx_date r_trx_date,
round(invr.extended_amount, 2) r_amount,
round(nvl(ps.amount_due_remaining, invr.extended_amount), 2) r_amount_due_rem,
round(invr.amount_without_credits - invf.extended_amount, 3) diff,
invf.trx_number f_trx_number,
invf.trx_date f_trx_date,
round(invf.extended_amount, 2) f_amount,
round(invr.extended_amount +
nvl((SELECT SUM(psa.amount_credited)
FROM ar_payment_schedules_all psa
WHERE psa.customer_trx_id = invr.customer_trx_id),
0) - invf.extended_amount,
1) NULLS,
round(nvl(ps.amount_due_remaining, (invr.extended_amount * 1.2)), 2) notnulls,
invr.org_id
FROM (SELECT cth.customer_trx_id,
cth.trx_number,
cth.trx_date,
SUM(ctl.extended_amount) * 1.2 extended_amount,
round(((SUM(ctl.extended_amount) * 1.2 +
nvl((SELECT SUM(psa.amount_credited)
FROM ar_payment_schedules_all psa
WHERE psa.customer_trx_id = cth.customer_trx_id),
0))),
2) amount_without_credits,
cth.org_id,
nvl(decode(TRIM(ctl.interface_line_attribute13),
0,
NULL,
TRIM(ctl.interface_line_attribute13)),
cth.interface_header_attribute13) interface_line_attribute13
FROM ra_customer_trx_all cth,
ra_customer_trx_lines_all ctl
WHERE cth.customer_trx_id = ctl.customer_trx_id AND
ctl.line_type = ''LINE'' AND
ctl.set_of_books_id = 1001
GROUP BY cth.customer_trx_id,
cth.trx_number,
cth.trx_date,
cth.org_id,
nvl(decode(TRIM(ctl.interface_line_attribute13),
0,
NULL,
TRIM(ctl.interface_line_attribute13)),
cth.interface_header_attribute13)) invr,
(SELECT cth.customer_trx_id,
cth.trx_number,
cth.trx_date,
SUM(ctl.extended_amount) * 1.2 extended_amount,
round(((SUM(ctl.extended_amount) * 1.2 +
nvl((SELECT SUM(psa.amount_credited)
FROM ar_payment_schedules_all psa
WHERE psa.customer_trx_id = cth.customer_trx_id),
0))),
2) amount_without_credits,
cth.org_id,
nvl(decode(TRIM(ctl.interface_line_attribute13),
0,
NULL,
TRIM(ctl.interface_line_attribute13)),
cth.interface_header_attribute13) interface_line_attribute13
FROM ra_customer_trx_all cth,
ra_customer_trx_lines_all ctl
WHERE cth.customer_trx_id = ctl.customer_trx_id AND
ctl.line_type = ''LINE'' AND
cth.set_of_books_id = 2001
GROUP BY cth.customer_trx_id,
cth.trx_number,
cth.trx_date,
cth.org_id,
nvl(decode(TRIM(ctl.interface_line_attribute13),
0,
NULL,
TRIM(ctl.interface_line_attribute13)),
cth.interface_header_attribute13)) invf,
ar_payment_schedules_all ps
WHERE invf.interface_line_attribute13(+) = invr.customer_trx_id AND
ps.customer_trx_id(+) = invr.customer_trx_id AND
invr.trx_date >= SYSDATE - ' ||
days_before_today || ' ' || lv_where_le_ids;
bpdev.bp_utils.put_log('Зареждане на новите данни.');
OPEN c_denormalized_data FOR lv_sql_str;
LOOP
FETCH c_denormalized_data
INTO r_denormalized_data;
EXIT WHEN c_denormalized_data%NOTFOUND;
INSERT INTO bpdev.bp_real_to_fiskal_reference
(r_customer_trx_id,
r_trx_number,
r_trx_date,
r_amount,
r_amount_due_rem,
diff,
f_trx_number,
f_trx_date,
f_amount,
NULLS,
notnulls,
org_id,
data_loaded_for_days)
VALUES
(r_denormalized_data.r_customer_trx_id,
r_denormalized_data.r_trx_number,
r_denormalized_data.r_trx_date,
r_denormalized_data.r_amount,
r_denormalized_data.r_amount_due_rem,
r_denormalized_data.diff,
r_denormalized_data.f_trx_number,
r_denormalized_data.f_trx_date,
r_denormalized_data.f_amount,
r_denormalized_data.nulls,
r_denormalized_data.notnulls,
r_denormalized_data.org_id,
days_before_today);
END LOOP;
COMMIT;
CLOSE c_denormalized_data;
bpdev.bp_utils.put_log('>>>------КРАЙ ПОТРЕБИТЕЛСКИ СЪОБЩЕНИЯ-----<<<');
EXCEPTION
WHEN OTHERS THEN
bpdev.bp_utils.put_log(retcode || errbuf);
END load_denormalized_data;
we dont have all info , but I suspect the problem is here
invr.trx_date >= SYSDATE - ' || days_before_today || ' ' || lv_where_le_ids;
try to add the date you expect as static then try again.

Why this regexp in Oracle SQL loses the beginning of string?

I'm splitting a string p_value using p_delimeter, which may contain one or more symbols (that's why regexp is not like often used [^,]+).
In most of the cases the following query works predictably, but I'm dazed with a case when:
string p_value contains line break chr(10),
p_value doesn't contain p_delimeter as substring,
so I expect to have one row with the whole p_value as the result, but got only the remainder after line break.
It's supposed here that regexp treats line break as ordinary symbol, since
the 'm' modifier is absent in call to regexp_substr.
Please, explain is this behavior correct and how to get the expected result.
WITH
params AS (SELECT 'ab' || chr(10) || 'cd' p_value,
'xxx' p_delimeter
FROM dual
)
SELECT regexp_substr(p_value, '(.*?)(' || p_delimeter || '|$)', 1, level, 'c', 1) AS CUT
FROM params
CONNECT BY regexp_substr(p_value, '(.*?)(' || p_delimeter || '|$)', 1, level, 'c', 1) IS NOT NULL;
Actual result: Expected result:
----- ------
CUT CUT
----- ------
cd ab/cd
^
'this is just a marker for a line break [= chr(10)]'
Allow the . pattern to match all characters by adding the n flag to the regular expression:
WITH params ( p_value, p_delimiter ) AS (
SELECT 'ab' || chr(10) || 'cd', 'xxx' FROM dual
)
SELECT REGEXP_SUBSTR(p_value, '(.*?)(' || p_delimeter || '|$)', 1, level, 'cn', 1) AS CUT
FROM params
CONNECT BY LEVEL < REGEXP_COUNT( p_value, '(.*?)(' || p_delimeter || '|$)' );
or you can use a simple function:
Oracle Setup:
CREATE TYPE VARCHAR2_TABLE AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION split_String(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT ','
) RETURN VARCHAR2_TABLE DETERMINISTIC
AS
p_result VARCHAR2_TABLE := VARCHAR2_TABLE();
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH( i_str );
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
IF c_len > 0 THEN
p_end := INSTR( i_str, i_delim, p_start );
WHILE p_end > 0 LOOP
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
p_start := p_end + c_ld;
p_end := INSTR( i_str, i_delim, p_start );
END LOOP;
IF p_start <= c_len + 1 THEN
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
END IF;
END IF;
RETURN p_result;
END;
/
Query:
WITH params ( p_value, p_delimiter ) AS (
SELECT 'ab' || chr(10) || 'cd', 'xxx' FROM dual
)
SELECT COLUMN_VALUE AS CUT
FROM params,
TABLE( split_String( p_value, p_delimiter ) );

SQL Server: HTML Decode based on the HTML names in a String input

I am trying to convert the HTML names like & " etc to their equivalent CHAR values using the SQL below. I was testing this in SQL Server 2012.
Test 1 (This works fine):
GO
DECLARE #inputString VARCHAR(MAX)= '&testString&'
DECLARE #codePos INT, #codeEncoded VARCHAR(7), #startIndex INT, #resultString varchar(max)
SET #resultString = LTRIM(RTRIM(#inputString))
SELECT #startIndex = PATINDEX('%&%', #resultString)
WHILE #startIndex > 0
BEGIN
SELECT #resultString = REPLACE(#resultString, '&', '&'), #startIndex=PATINDEX('%&%', #resultString)
END
PRINT #resultString
Go
Output:
&testString&
Test 2 (this isn't worked):
Since the above worked, I have tried to extend this to deal with more characters as following:
DECLARE #htmlNames TABLE (ID INT IDENTITY(1,1), asciiDecimal INT, htmlName varchar(50))
INSERT INTO #htmlNames
VALUES (34,'"'),(38,'&'),(60,'<'),(62,'>'),(160,' '),(161,'¡'),(162,'¢')
-- I would load the full list of HTML names into this TABLE varaible, but removed for testing purposes
DECLARE #inputString VARCHAR(MAX)= '&testString&'
DECLARE #count INT = 0
DECLARE #id INT = 1
DECLARE #charCode INT, #htmlName VARCHAR(30)
DECLARE #codePos INT, #codeEncoded VARCHAR(7), #startIndex INT
, #resultString varchar(max)
SELECT #count=COUNT(*) FROM #htmlNames
WHILE #id <=#count
BEGIN
SELECT #charCode = asciiDecimal, #htmlname = htmlName
FROM #htmlNames
WHERE ID = #id
SET #resultString = LTRIM(RTRIM(#inputString))
SELECT #startIndex = PATINDEX('%' + #htmlName + '%', #resultString)
While #startIndex > 0
BEGIN
--PRINT #resultString + '|' + #htmlName + '|' + NCHAR(#charCode)
SELECT #resultString = REPLACE(#resultString, #htmlName, NCHAR(#charCode))
SET #startIndex=PATINDEX('%' + #htmlName + '%', #resultString)
END
SET #id=#id + 1
END
PRINT #resultString
GO
Output:
&testString&
I cannot figure out where I'm going wrong? Any help would be much appreciated.
I am not interested to load the string values into application layer and then apply HTMLDecode and save back to the database.
EDIT:
This line SET #resultString = LTRIM(RTRIM(#inputString)) was inside the WHILE so I was overwriting the result with #inputString. Thank you, YanireRomero.
I like #RichardDeeming's solution too, but it didn't suit my needs in this case.
Here's a simpler solution that doesn't need a loop:
DECLARE #htmlNames TABLE
(
ID INT IDENTITY(1,1),
asciiDecimal INT,
htmlName varchar(50)
);
INSERT INTO #htmlNames
VALUES
(34,'"'),
(38,'&'),
(60,'<'),
(62,'>'),
(160,' '),
(161,'¡'),
(162,'¢')
;
DECLARE #inputString varchar(max)= '&test&quot;<String>"&';
DECLARE #resultString varchar(max) = #inputString;
-- Simple HTML-decode:
SELECT
#resultString = Replace(#resultString COLLATE Latin1_General_CS_AS, htmlName, NCHAR(asciiDecimal))
FROM
#htmlNames
;
SELECT #resultString;
-- Output: &test"<String>"&
-- Multiple HTML-decode:
SET #resultString = #inputString;
DECLARE #temp varchar(max) = '';
WHILE #resultString != #temp
BEGIN
SET #temp = #resultString;
SELECT
#resultString = Replace(#resultString COLLATE Latin1_General_CS_AS, htmlName, NCHAR(asciiDecimal))
FROM
#htmlNames
;
END;
SELECT #resultString;
-- Output: &test"<String>"&
EDIT: Changed to NCHAR, as suggested by #tomasofen, and added a case-sensitive collation to the REPLACE function, as suggested by #TechyGypo.
For the sake of performance, this isn't something you should do write as T-SQL statements, or as a SQL scalar value function. The .NET libraries provide excellent, fast, and, above all, reliable HTML decoding. In my opinion, you should implement this as a SQL CLR, like this:
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(
IsDeterministic = true,
IsPrecise = true,
DataAccess = DataAccessKind.None,
SystemDataAccess = SystemDataAccessKind.None)]
[return: SqlFacet(MaxSize = 4000)]
public static SqlString cfnHtmlDecode([SqlFacet(MaxSize = 4000)] SqlString input)
{
if (input.IsNull)
return null;
return System.Net.WebUtility.HtmlDecode(input.Value);
}
}
Then in your T-SQL, call it like this:
SELECT clr_schema.cfnHtmlDecode(column_name) FROM table_schema.table_name
Hey it was an assign error:
DECLARE #htmlNames TABLE (ID INT IDENTITY(1,1), asciiDecimal INT, htmlName varchar(50))
INSERT INTO #htmlNames
VALUES (34,'"'),(38,'&'),(60,'<'),(62,'>'),(160,' '),(161,'¡'),(162,'¢')
-- I would load the full list of HTML names into this TABLE varaible, but removed for testing purposes
DECLARE #inputString VARCHAR(MAX)= '&testString&'
DECLARE #count INT = 0
DECLARE #id INT = 1
DECLARE #charCode INT, #htmlName VARCHAR(30)
DECLARE #codePos INT, #codeEncoded VARCHAR(7), #startIndex INT
, #resultString varchar(max)
SELECT #count=COUNT(*) FROM #htmlNames
SET #resultString = LTRIM(RTRIM(#inputString))
WHILE #id <=#count
BEGIN
SELECT #charCode = asciiDecimal, #htmlname = htmlName
FROM #htmlNames
WHERE ID = #id
SELECT #startIndex = PATINDEX('%' + #htmlName + '%', #resultString)
While #startIndex > 0
BEGIN
--PRINT #resultString + '|' + #htmlName + '|' + NCHAR(#charCode)
SET #resultString = REPLACE(#resultString, #htmlName, NCHAR(#charCode))
SET #startIndex=PATINDEX('%' + #htmlName + '%', #resultString)
END
SET #id=#id + 1
END
PRINT #resultString
GO
this line SET #resultString = LTRIM(RTRIM(#inputString)) was inside the while so you were overwriting you result.
Hope it helps.
Some additional help for "Richard Deeming" response, to safe some typing for future visitors trying to upgrade the function with more codes:
INSERT INTO #htmlNames
VALUES
(34,'"'),
(38,'&'),
(60,'<'),
(62,'>'),
(160, ' '),
(161, '¡'),
(162, '¢'),
(163, '£'),
(164, '¤'),
(165, '¥'),
(166, '¦'),
(167, '§'),
(168, '¨'),
(169, '©'),
(170, 'ª'),
(171, '«'),
(172, '¬'),
(173, '­'),
(174, '®'),
(175, '¯'),
(176, '°'),
(177, '±'),
(178, '²'),
(179, '³'),
(180, '´'),
(181, 'µ'),
(182, '¶'),
(183, '·'),
(184, '¸'),
(185, '¹'),
(186, 'º'),
(187, '»'),
(188, '¼'),
(189, '½'),
(190, '¾'),
(191, '¿'),
(192, 'À'),
(193, 'Á'),
(194, 'Â'),
(195, 'Ã'),
(196, 'Ä'),
(197, 'Å'),
(198, 'Æ'),
(199, 'Ç'),
(200, 'È'),
(201, 'É'),
(202, 'Ê'),
(203, 'Ë'),
(204, 'Ì'),
(205, 'Í'),
(206, 'Î'),
(207, 'Ï'),
(208, 'Ð'),
(209, 'Ñ'),
(210, 'Ò'),
(211, 'Ó'),
(212, 'Ô'),
(213, 'Õ'),
(214, 'Ö'),
(215, '×'),
(216, 'Ø'),
(217, 'Ù'),
(218, 'Ú'),
(219, 'Û'),
(220, 'Ü'),
(221, 'Ý'),
(222, 'Þ'),
(223, 'ß'),
(224, 'à'),
(225, 'á'),
(226, 'â'),
(227, 'ã'),
(228, 'ä'),
(229, 'å'),
(230, 'æ'),
(231, 'ç'),
(232, 'è'),
(233, 'é'),
(234, 'ê'),
(235, 'ë'),
(236, 'ì'),
(237, 'í'),
(238, 'î'),
(239, 'ï'),
(240, 'ð'),
(241, 'ñ'),
(242, 'ò'),
(243, 'ó'),
(244, 'ô'),
(245, 'õ'),
(246, 'ö'),
(247, '÷'),
(248, 'ø'),
(249, 'ù'),
(250, 'ú'),
(251, 'û'),
(252, 'ü'),
(253, 'ý'),
(254, 'þ'),
(255, 'ÿ'),
(8364, '€');
EDITED:
If you want the euro symbol working (and in general ASCII codes over 255), you will need to use NCHAR instead CHAR in Richard Deeming code.

Multiple tables in SELECT query

I'm trying to select columns from multiple tables. Here's the code I have:
SELECT
Sum(IIf((tblChain.InitialZone="1"),1,0)) AS SCCH,
tblStatHistory.HomeTeam,
Sum(IIf(([Pentagraph]="HANDB") Or ([Pentagraph]="HANBB") Or ([Pentagraph]="HBCL") Or
([Pentagraph]="KBBW") Or ([Pentagraph]="KBCL") Or ([Pentagraph]="KBIN") Or
([Pentagraph]="KBLO") Or ([Pentagraph]="KBSH") Or ([Pentagraph]="KKBW") Or
([Pentagraph]="KKCL") Or ([Pentagraph]="KKGKN") Or ([Pentagraph]="KKBW") Or
([Pentagraph]="KKGKO") Or ([Pentagraph]="KKGKP") Or([Pentagraph]="KKIN") Or
([Pentagraph]="KKLO") Or ([Pentagraph]="KKSH"),1,0)) AS D,
Sum(IIf(([Pentagraph]="KBBW") Or ([Pentagraph]="KBCL") Or ([Pentagraph]="KBIN") Or
([Pentagraph]="KBLO") Or ([Pentagraph]="KBSH") Or ([Pentagraph]="KKBW") Or
([Pentagraph]="KKCL") Or ([Pentagraph]="KKGKN") Or ([Pentagraph]="KKBW") Or
([Pentagraph]="KKGKO") Or ([Pentagraph]="KKGKP") Or ([Pentagraph]="KKIN") Or
([Pentagraph]="KKLO") Or ([Pentagraph]="KKSH"),1,0)) AS K,
Sum(IIf(([Pentagraph]="KBBW") Or ([Pentagraph]="KKBW"),1,0)) AS K_Back,
Sum(IIf(([Pentagraph]="MACOO") Or ([Pentagraph]="MACOP") Or ([Pentagraph]="MAPAO") Or
([Pentagraph]="MAPAP") Or ([Pentagraph]="MAOL") Or ([Pentagraph]="MAUNO") Or
([Pentagraph]="MAUNP"),1,0)) AS M,
Sum(IIf(([Pentagraph]="MAERO") Or ([Pentagraph]="MAERP") Or ([Pentagraph]="MAUNO") Or
([Pentagraph]="MAUC") Or ([Pentagraph]="MAUNP") Or ([Pentagraph]="MAOL"),1,0)) AS UM,
Sum(IIf(([Pentagraph]="MACOO") Or ([Pentagraph]="MACOP"),1,0)) AS CM,
Sum(IIf(([Pentagraph]="HANDB") Or ([Pentagraph]="HANBB") Or ([Pentagraph]="HBCL"),1,0)) AS H,
Sum(IIf(([Pentagraph]="CBCL") Or ([Pentagraph]="BUCL") Or ([Pentagraph]="TICL"),1,0)) AS C,
Sum(IIf(([Pentagraph]="CBCL"),1,0)) AS C_CSB,
Sum(IIf(([Pentagraph]="BUCL") Or ([Pentagraph]="TICL"),1,0)) AS C_BUTI,
Sum(IIf(([Pentagraph]="CBFP") Or ([Pentagraph]="BUFP") Or ([Pentagraph]="TIFP"),1,0)) AS FP,
Sum(IIf(([Pentagraph]="BUFP") Or ([Pentagraph]="TIFP"),1,0)) AS FP_BUTI,
Sum(IIf(([Pentagraph]="CBFP"),1,0)) AS FP_CSB,
Sum(IIf(([Pentagraph]="CBHO") Or ([Pentagraph]="BUHO") Or ([Pentagraph]="TIHO"),1,0)) AS HO,
Sum(IIf(([Pentagraph]="BUHO") Or ([Pentagraph]="TIHO"),1,0)) AS HO_BUTI,
Sum(IIf(([Pentagraph]="CBHO"),1,0)) AS HO_CSB,
Sum(IIf(([Pentagraph]="IN50"),1,0)) AS I50,
Sum(IIf(([Pentagraph]="GOAL"),1,0)) AS GOAL,
Sum(IIf(([Pentagraph]="BEHI"),1,0)) AS BHND,
Sum(IIf(([Pentagraph]="TACKN") Or ([Pentagraph]="TACKO") Or ([Pentagraph]="TACKP") Or
(([Pentagraph]="RDTDD") And ([ROLE]=1)) Or (([Pentagraph]="TACKL") And ([ROLE]=1)) Or
(([Pentagraph]="RDTAK") And ([ROLE]=1)) Or (([Pentagraph]="DISP") And ([ROLE]=1)),1,0)) AS T,
Sum(IIf(([Pentagraph]="GEHAN") Or ([Pentagraph]="GEHAO") Or ([Pentagraph]="GEHAP") Or ([Pentagraph]="GEHCN") Or ([Pentagraph]="GEHCO") Or([Pentagraph]="GEHCP") Or
([Pentagraph]="GERU") Or ([Pentagraph]="GELON") Or ([Pentagraph]="GELOO") Or ([Pentagraph]="GELOP") Or ([Pentagraph]="GELCN") Or ([Pentagraph]="GELCO") Or ([Pentagraph]="GELCP"),1,0)) AS GB
FROM
tblStatHistory
WHERE
(((tblStatHistory.Period)=IIf(:QTR1,1) Or (tblStatHistory.Period)=IIf(:QTR2,2) Or
(tblStatHistory.Period)=IIf(:QTR3,3) Or (tblStatHistory.Period)=IIf(:QTR4,4)) AND
((tblStatHistory.LogicalZone)=IIf(:ZONEF50,"F") Or (tblStatHistory.LogicalZone)=IIf(:ZONEAM,"S") Or
(tblStatHistory.LogicalZone)=IIf(:ZONEDM,"R") Or (tblStatHistory.LogicalZone)=IIf(:ZONED50,"D")) AND
((tblStatHistory.MatchID)=:GameID) AND ((tblStatHistory.PeriodSecs)>:Seconds))
GROUP BY
tblStatHistory.HomeTeam
ORDER BY
tblStatHistory.HomeTeam DESC;
This part of the very first line is the second table I'm trying to access
Sum(IIf((tblChain.InitialZone="1"),1,0)) AS SCCH
What's happening is if I try write the value of "SCCH" to a variable, it's spitting back that the SCCH field is empty. It also kills the output from the rest of the code, reporting 0 instead of the count of the query.
Any suggestions on how to best implement this?
EDIT: Here is the original code
Procedure TGame.UpdateTeamStats;
var
Query: TADOQuery;
P,Z,T: integer;
begin
try
Query := TADOQuery.Create(nil);
Query.Connection := connection;
Query.Close;
Query.SQL.Add('SELECT tblStatHistory.HomeTeam, Sum(IIf(([Pentagraph]="HANDB") Or ');
Query.SQL.Add('([Pentagraph]="HANBB") Or ([Pentagraph]="HBCL") Or ([Pentagraph]="KBBW") Or ([Pentagraph]="KBCL") Or ');
Query.SQL.Add('([Pentagraph]="KBIN") Or ([Pentagraph]="KBLO") Or ([Pentagraph]="KBSH") Or ');
Query.SQL.Add('([Pentagraph]="KKBW") Or ([Pentagraph]="KKCL") Or ([Pentagraph]="KKGKN") Or ');
Query.SQL.Add('([Pentagraph]="KKBW") Or ([Pentagraph]="KKGKO") Or ([Pentagraph]="KKGKP") Or ');
Query.SQL.Add('([Pentagraph]="KKIN") Or ([Pentagraph]="KKLO") Or ([Pentagraph]="KKSH"),1,0)) AS D, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="KBBW") Or ([Pentagraph]="KBCL") Or ([Pentagraph]="KBIN") Or ');
Query.SQL.Add('([Pentagraph]="KBLO") Or ([Pentagraph]="KBSH") Or ([Pentagraph]="KKBW") Or ');
Query.SQL.Add('([Pentagraph]="KKCL") Or ([Pentagraph]="KKGKN") Or ([Pentagraph]="KKBW") Or ');
Query.SQL.Add('([Pentagraph]="KKGKO") Or ([Pentagraph]="KKGKP") Or ([Pentagraph]="KKIN") Or ');
Query.SQL.Add('([Pentagraph]="KKLO") Or ([Pentagraph]="KKSH"),1,0)) AS K, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="MACOO") Or ([Pentagraph]="MACOP") Or ([Pentagraph]="MAPAO") Or ');
Query.SQL.Add('([Pentagraph]="MAPAP") Or ([Pentagraph]="MAOL") Or ([Pentagraph]="MAUNO") Or ');
Query.SQL.Add('([Pentagraph]="MAUNP"),1,0)) AS M, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="MAERO") Or ([Pentagraph]="MAERP") Or ([Pentagraph]="MAUNO") Or ');
Query.SQL.Add('([Pentagraph]="MAUC") Or ([Pentagraph]="MAUNP") Or ([Pentagraph]="MAOL"),1,0)) AS UM, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="MACOO") Or ([Pentagraph]="MACOP"),1,0)) AS CM, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="KBBW") Or ([Pentagraph]="KKBW"),1,0)) AS K_Back, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="HANDB") Or ([Pentagraph]="HANBB") Or ([Pentagraph]="HBCL"),1,0)) AS H, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="CBCL") Or ([Pentagraph]="BUCL") Or ([Pentagraph]="TICL"),1,0)) AS C, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="CBCL"),1,0)) AS C_CSB, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="BUCL") Or ([Pentagraph]="TICL"),1,0)) AS C_BUTI, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="CBFP") Or ([Pentagraph]="BUFP") Or ([Pentagraph]="TIFP"),1,0)) AS FP, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="BUFP") Or ([Pentagraph]="TIFP"),1,0)) AS FP_BUTI, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="CBFP"),1,0)) AS FP_CSB, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="CBHO") Or ([Pentagraph]="BUHO") Or ([Pentagraph]="TIHO"),1,0)) AS HO, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="BUHO") Or ([Pentagraph]="TIHO"),1,0)) AS HO_BUTI, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="CBHO"),1,0)) AS HO_CSB, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="IN50"),1,0)) AS I50, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="GOAL"),1,0)) AS GOAL, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="BEHI"),1,0)) AS BHND, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="TACKN") Or ([Pentagraph]="TACKO") Or ([Pentagraph]="TACKP") Or ');
Query.SQL.Add('(([Pentagraph]="RDTDD") And ([ROLE]=1)) Or (([Pentagraph]="TACKL") And ([ROLE]=1)) Or ');
Query.SQL.Add('(([Pentagraph]="RDTAK") And ([ROLE]=1)) Or (([Pentagraph]="DISP") And ([ROLE]=1)),1,0)) AS T, ');
Query.SQL.Add('Sum(IIf(([Pentagraph]="GEHAN") Or ([Pentagraph]="GEHAO") Or ([Pentagraph]="GEHAP") Or ([Pentagraph]="GEHCN") Or ([Pentagraph]="GEHCO") Or([Pentagraph]="GEHCP") Or ');
Query.SQL.Add('([Pentagraph]="GERU") Or ([Pentagraph]="GELON") Or ([Pentagraph]="GELOO") Or ([Pentagraph]="GELOP") Or ([Pentagraph]="GELCN") Or ([Pentagraph]="GELCO") Or ([Pentagraph]="GELCP"),1,0)) AS GB');
Query.SQL.Add('FROM tblStatHistory');
Query.SQL.Add('WHERE (((tblStatHistory.Period)=IIf(:QTR1,1) Or (tblStatHistory.Period)=IIf(:QTR2,2) Or ');
Query.SQL.Add('(tblStatHistory.Period)=IIf(:QTR3,3) Or (tblStatHistory.Period)=IIf(:QTR4,4)) AND ');
Query.SQL.Add('((tblStatHistory.LogicalZone)=IIf(:ZONEF50,"F") Or (tblStatHistory.LogicalZone)=IIf(:ZONEAM,"S") Or ');
Query.SQL.Add('(tblStatHistory.LogicalZone)=IIf(:ZONEDM,"R") Or (tblStatHistory.LogicalZone)=IIf(:ZONED50,"D")) AND ');
Query.SQL.Add('((tblStatHistory.MatchID)=:GameID) AND ((tblStatHistory.PeriodSecs)>:Seconds))');
Query.SQL.Add('GROUP BY tblStatHistory.HomeTeam');
Query.SQL.Add('ORDER BY tblStatHistory.HomeTeam DESC;');
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'GameID';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'Seconds';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'QTR1';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'QTR2';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'QTR3';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'QTR4';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'ZONEF50';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'ZONEAM';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'ZONEDM';
end;
with Query.Parameters.AddParameter do
begin
DataType := ftinteger;
name:= 'ZONED50';
end;
Query.Parameters.ParamByName('GameID').Value := GameID;
for P := 0 to 4 do
begin
if updatePeriodCheck(p) then
begin
for Z := 0 to 7 do
begin
SetParameters(P,Z,0,Query.Parameters);
Query.Open;
Query.First;
for T := 0 to 3 do
begin
if T = 1 then Query.Next;
if T < 2 then
Stats[P,Z].Team[T] := PopulateStatsRecord(Query)
else if T = 2 then // Difference
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,Z].Team[1],Stats[P,Z].Team[0])
else if T=3 then begin // Difference Z v Z
if Z = 0 then
Stats[P,Z].Team[T] := Stats[P,Z].Team[2]
else if Z = 1 then
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,1].Team[1],Stats[P,4].Team[0])
else if Z = 2 then
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,2].Team[1],Stats[P,3].Team[0])
else if Z = 3 then
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,3].Team[1],Stats[P,4].Team[0])
else if Z = 4 then
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,4].Team[1],Stats[P,1].Team[0])
else if Z = 5 then
Stats[P,Z].Team[T] := Stats[P,Z].Team[2]
else if z = 6 then
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,6].Team[1],Stats[P,7].Team[0])
else if z = 7 then
Stats[P,Z].Team[T] := SubtractStatsRecords(Stats[P,7].Team[1],Stats[P,6].Team[0]);
end;
end;
Query.Close;
end;
end;
end;
finally
Query.Free;
end;
end;