Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1svDLT-00DEG7-Ix for pgsql-general@arkaria.postgresql.org; Mon, 30 Sep 2024 10:09:36 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1svDLS-00FtCz-UL for pgsql-general@arkaria.postgresql.org; Mon, 30 Sep 2024 10:09:34 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1svDLS-00FtBl-FQ for pgsql-general@lists.postgresql.org; Mon, 30 Sep 2024 10:09:34 +0000 Received: from mail-oo1-xc33.google.com ([2607:f8b0:4864:20::c33]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1svDLP-001m49-T6 for pgsql-general@lists.postgresql.org; Mon, 30 Sep 2024 10:09:33 +0000 Received: by mail-oo1-xc33.google.com with SMTP id 006d021491bc7-5dfad5a9c21so2309295eaf.0 for ; Mon, 30 Sep 2024 03:09:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1727690971; x=1728295771; darn=lists.postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=B6WHkgifO66gB1nKEGQqyBzz0I67IE2jDfVveeRm0nc=; b=AAek/ukDyC2bAkuZv9+iXQPBgC/ocsFDIvoX01j7RMfbQAEeH7XTAQCxqTQYJfnDGA YP9sOy2IWccd7kE32Axh5Wv2thfOGnf20e8Gp0GUXR4IJxtq4sN87uQdx8eyicM1ry9k ilSArFZQ0svsmt43Ir7UIR2thr2hAqVON/ODKU12l/J51FTv2DzeeKGZ1DKSLSgp88Wr 2nTOOVW6TfD8gpLuwsDwYWUI0Axic7ENc8OZkdAFHbHtlesObRnrldskU8tLbVColiXN qoryg2IpOKUzo7y0i9tctgSggjd/lc8EtCFBmhIYUNp+CzFPMGVdbWb/cGmiTjNHIeHw 648g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1727690971; x=1728295771; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=B6WHkgifO66gB1nKEGQqyBzz0I67IE2jDfVveeRm0nc=; b=k0zM5sHEXm1mZa4jeD+C9qhj0QdOTSly/lqyruIr7/y0ch369gmvtfq3zKnsiOy0j/ sKt1AN5jgGqQ9FKwJ4JhbX8mjahkJqSta7xuOwEnJi9FcA4/nMxcN1ax0hMeBZajADdP ZC6Ftn0yhuATo8NS33SzROpFxZ9gvgnf/n1JqjqggL26V5YQCAn0LDu6rMXVowKAIkat t7ea+B/WD1AneKbl3GfhRrY/eEYEQYI/JCf1shhN+e0B0DxN7jsWEEwtYKIhw9hhozuZ PD47kY4ayn0uqj8/4MoyehkwdlVSyAcCvfXy+9ayPiKDJ3yCtHZ+QY5X+OXLpUz5vgWq dNgw== X-Gm-Message-State: AOJu0YwGKdVvfbw8hGnDi7aim0ROqaRD0aQgwQfGqhEl22YK59MzzupE aQKNSBvoFNpEd3UnXjdvTnBuJkluTJP/YORcxt1T9Pa84hFOk+7Of16mu1d2bVpFzAZJnHuoU2h k/wH6BpjJwkHBuJiUrhJ+SuxYaJ7lORWd X-Google-Smtp-Source: AGHT+IF0ZqZjr2yIcjMDFuAuMG+pBt+bDeNc6Gi3O0CSeNCXflVrFgU/OJqfWNxTlZP1GrPugLy5S7wXBOeKjeJBo5s= X-Received: by 2002:a05:6820:61e:b0:5c4:144b:1ff9 with SMTP id 006d021491bc7-5e7727c46fdmr7144793eaf.5.1727690970751; Mon, 30 Sep 2024 03:09:30 -0700 (PDT) MIME-Version: 1.0 From: Nikhil Ingale Date: Mon, 30 Sep 2024 15:38:54 +0530 Message-ID: Subject: Trouble in generating the plpgsql procedure code To: pgsql-general@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000097e8e306235366e4" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000097e8e306235366e4 Content-Type: text/plain; charset="UTF-8" Guys, I have a requirement to generate the plpgsql procedure code itself by reading the postgresql metadata or system tables. I don't want to write a plpgsql procedure every time for every table because I have many tables in db. I want to generate the procedure for more than 100 tables and write all the procedure code to a single file which can be used to execute to create the actual procedure. While I generate the procedure code I want the code to be added to the next line in a better readability format. I'm writing the generated code for all tables in single shot with the help of COPY to PROG My procedure code is mentioned below. But the generated code is having \n instead of adding the code to the next line. CREATE OR REPLACE FUNCTION emp_dts_iot () RETURNS TRIGGER AS $BODY$\nDECLARE\n nCount INT;\nBEGIN\n IF TG_OP IN ('INSERT') THEN\n SELECT count(1) INTO nCount FROM employee \n WHERE id = :NEW.id AND STATUS_FLAG = 9 ; \n IF COALESCE(nCount,0) > 0 THEN\n UPDATE test.employee \n id = :NEW.\n ,description = :NEW.description\n ,state_flag = 2\n WHERE id = :NEW.id ; \n ELSE\n\t INSERT INTO employee VALUES ( \n :NEW.id\n ,:NEW.description\n ,1 ) ; \n END IF;\n\n ELSIF TG_OP IN ('UPDATE') THEN\n SELECT count(1) INTO nCount FROM test.employee\n The code should have been written in the next line instead of \n. drop procedure insteadoftriggers; create or replace procedure insteadoftriggers( IN e_owner TEXT, p_table_name TEXT DEFAULT NULL, emp_owner TEXT DEFAULT 'test') AS $$ DECLARE TstTableCursor CURSOR IS SELECT table_name,test_table_name FROM app_tables WHERE TEST_TABLE_NAME IS NOT NULL AND table_name = COALESCE(p_table_name,table_name) AND owner= COALESCE(e_owner,owner) ; l_cnt NUMERIC := 0; tab TEXT := E'\t'; l_col_str TEXT; l_table_Name TEXT ; cKeyCol TEXT DEFAULT '' ; cWhere TEXT DEFAULT '' ; trigger_body TEXT ; cSpace character varying(100) := ' '; BEGIN FOR TstTableRec IN TstTableCursor LOOP l_table_name := TstTableRec.TABLE_NAME ; trigger_body := 'CREATE OR REPLACE FUNCTION prod.' || TstTableRec.TABLE_NAME || '_IOT() RETURNS TRIGGER AS $BODY$' || CHR(10) || 'DECLARE' || CHR(10) || ' ' || 'nCount INT;' || chr(10) || 'BEGIN' || chr(10) || ' ' || 'IF TG_OP IN ' || '(' ||'''''INSERT'''''||') THEN' || chr(10) || ' SELECT count(1) INTO nCount FROM test.' || TstTableRec.TABLE_NAME || chr(10) || GetTrigClause(p_tdaowner, lower(TstTableRec.TABLE_NAME), ':NEW.') || ' AND STATUS_FLAG = 9 ; ' || chr(10) || ' '|| 'IF COALESCE(nCount,0) > 0 THEN' || chr(10) || Can someone help me here? Regards, Nikhil Ingale --00000000000097e8e306235366e4 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Guys,
I have a requirement to generate the plpgsql pro= cedure code itself by reading the postgresql metadata or system tables. I d= on't want to write a plpgsql procedure every time for every table becau= se I have many tables in db. I want to generate the procedure for more than= 100 tables and write all the procedure code to a single file which can be = used to execute to create the actual procedure.

While I generate the= procedure code I want the code to be added to the next line in a better re= adability format. I'm writing the generated code for all tables in sing= le shot with the help of COPY to PROG

My procedure= code is mentioned below. But the generated code is having \n instead of ad= ding the code to the next line.


CRE= ATE OR REPLACE FUNCTION emp_dts_iot () RETURNS TRIGGER AS $BODY$\nDECLARE\n= =C2=A0nCount INT;\nBEGIN\n =C2=A0 IF TG_OP IN ('INSERT') THEN\n = =C2=A0 =C2=A0 =C2=A0 =C2=A0 SELECT count(1) INTO nCount FROM employee \n = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 WHERE id =3D :NEW.i= d AND STATUS_FLAG =3D 9 ; \n =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0IF COALESCE(nCount,0) > 0 THEN\n =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 UPDATE test.employee=C2=A0 \n=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 id =3D :NEW.\n =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ,description =3D :NEW.desc= ription\n =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ,s= tate_flag =3D 2\n =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 W= HERE id =3D :NEW.id ; \n =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0EL= SE\n\t =C2=A0 =C2=A0 =C2=A0 =C2=A0 INSERT INTO employee VALUES ( \n =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 :NEW.id\n =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ,:NEW.description\n= =C2=A0 =C2=A0 ,1 ) ; \n =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0END= IF;\n\n =C2=A0 ELSIF TG_OP IN ('UPDATE') THEN\n =C2=A0 =C2=A0 =C2= =A0 =C2=A0 SELECT count(1) INTO nCount FROM test.employee\n=C2=A0 =C2=A0=C2= =A0

The code should have been written in the n= ext line instead of \n.


drop procedure instead= oftriggers;
create or replace procedure insteadoftriggers( IN e_owner TE= XT, p_table_name TEXT DEFAULT NULL, emp_owner TEXT DEFAULT 'test')<= br>AS $$
DECLARE
=C2=A0 =C2=A0 TstTableCursor CURSOR IS SELECT table_= name,test_table_name FROM app_tables WHERE TEST_TABLE_NAME IS NOT NULL AND = table_name =3D COALESCE(p_table_name,table_name) AND owner=3D COALESCE(e_ow= ner,owner) ;
=C2=A0 =C2=A0
l_cnt NUMERIC :=3D 0;
=C2=A0 =C2= =A0 tab TEXT :=3D E'\t';
=C2=A0 =C2=A0 l_col_str TEXT;
=C2=A0= =C2=A0 l_table_Name TEXT ;
=C2=A0 =C2=A0 cKeyCol TEXT DEFAULT ''= ; ;
=C2=A0 =C2=A0 cWhere TEXT DEFAULT '' ;
=C2=A0 =C2=A0 trig= ger_body TEXT ;
=C2=A0 =C2=A0 cSpace character varying(100) :=3D ' = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ';
BEGIN
=C2=A0 =C2=A0 FOR Tst= TableRec IN TstTableCursor
=C2=A0 =C2=A0 LOOP
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 l_table_name :=3D TstTableRec.TABLE_NAME ;
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 trigger_body :=3D
'CREATE OR REPLACE FUNCTION prod.' || T= stTableRec.TABLE_NAME || '_IOT() RETURNS TRIGGER AS $BODY$' || CHR(= 10) ||
'DECLARE' || CHR(10) ||
' =C2=A0' || 'nCou= nt INT;' || chr(10) ||
'BEGIN' || chr(10) ||
' =C2=A0= ' || 'IF TG_OP IN ' || '(' ||'''''= INSERT'''''||') THEN' || chr(10) ||
' = =C2=A0 =C2=A0 =C2=A0 =C2=A0 SELECT count(1) INTO nCount FROM test.' || = TstTableRec.TABLE_NAME || chr(10) ||
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = GetTrigClause(p_tdaowner, lower(TstTableRec.TABLE_NAME), ':NEW.') |= | ' AND STATUS_FLAG =3D 9 ; ' || chr(10) ||

=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0' =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&= #39;|| 'IF COALESCE(nCount,0) > 0 THEN' || chr(10) ||

Can= someone help me here?

Regards,
Nikhil Ingale
--00000000000097e8e306235366e4--