How do you identify the triggers associated with a table in a informix database? - triggers

How can we identify the triggers associated with a table in a Informix database?

select tabname,a.* from systriggers a, systables b
where a.tabid=b.tabid and tabname="TableName"
or
dbschema -d db -t tablename

The information is in the SysTriggers and SysTrigBody system catalog tables — primarily SysTriggers. You can find the description of these (and all other system catalog tables) in the Informix Guide to SQL: Reference manual. You can find that at the Informix 11.70 Info Centre. In particular, the tabid (from SysTables) identifies the triggers for a table in SysTriggers.

As Jonathan answered you can use systriggers and other system catalog tables. I used them in my schema reporting utility: http://code.activestate.com/recipes/576621-dump-informix-schema-to-text/
This utility can work with Python and ODBC or with Jython and JDBC. It shows info about trigger for every table like:
--- triggers ---
defbookacc defbookacc_dtrg D
defbookacc defbookacc_itrg I
defbookacc defbookacc_utrg U
mc_loadman loadman_del D
and then shows body for each trigger.

--OBTIENE LOS TRIGGERS DE LA TABLA:
SELECT T.tabid, TRIM(T.owner) owner, T.tabname, TR.trigid, TRIM(TR.owner) tr_owner, TR.trigname, TR.event, TR.old, TR.new, TR.mode, TRIM(TR.collation) collation,
TB.datakey, TB.seqno, TB.data
FROM systables T, systriggers TR, systrigbody TB
WHERE T.tabname = 'table_name' AND TR.tabid = T.tabid AND TB.trigid = TR.trigid AND TB.datakey IN ('D', 'A')
ORDER BY TB.trigid, TB.datakey DESC, TB.seqno ASC;
--Event: type of triggering event: D = Delete trigger, I = Insert trigger ,U = Update trigger ,S = Select trigger , d = INSTEAD OF Delete trigger , i = INSTEAD OF Insert trigger ,u = INSTEAD OF Update trigger (IDS)
--Old: Name of value before update.
--New: Name of value after update.
--DataKey: Code specifying the type of data: A = ASCII text for the body, triggered actions, B = Linearized code for the body, D = English text for the header, trigger definition, H = Linearized code for the header, S = Linearized code for the symbol table.

Related

How create Oracle procedure witch select with dblink from postgres

I can select(in Oracle) from postgers with dblink, and its work fine.
But if i create procedure with this select:
Procedure:
`CREATE OR REPLACE PROCEDURE test_merge as
begin
MERGE INTO CARDS C
USING (SELECT c."card_id", 1, n."channel"
FROM "table_1"#DBLINK_NAME n
JOIN
"table_2"#DBLINK_NAME c
ON n."card_id" = c."id"
WHERE n."type" = 'param1') B
ON (C.CARDID = B."card_id")
WHEN MATCHED
THEN
UPDATE SET C.SENDR = 1, C.PHONE = '+' || B."channel";
end;`
ORA-04052: error occurred when looking up remote object postgres.table_name#DBLINK_NAME ORA-00604: error occurred at recursive SQL level 1 ORA-28500: connection from ORACLE to a non-Oracle system return this message: ERROR: relation "postgres.card" does
Have any idea?
Oracle 11g
Thanks!
It was necessary to specify the owner of the database on postgre. In my case, it was enough to specify "public". in the procedure. before accessing tables.
"public"."table_1"#DBLINK_NAME

oracle merge query in postgres

I have this merge query in oracle and it was working fine. Now we are migrating to postgres 10 and trying to find equivalent for this in postgres.
MERGE INTO s.act_pack C USING((SELECT A.jid, A.pid, B.pcode,
B.mc, A.md, A.hd FROM s.act_pack A INNER JOIN s.act_pack B
ON A.pid = B.pid AND A.pcode = B.mc AND (A.hd <> B.hd
OR A.md<> B.md)) order by A.upd_ts desc) D ON(C.pid = D.pid AND
C.pcode = D.pcode AND C.jid = D.jid) WHEN MATCHED THEN UPDATE SET C.md =
D.md, C.hd= D.hd;
I see some forums on web says postgres doesnt support merge, and use INSERT ... ON CONFLICT
but with no background in postgres, I am not able to understand how this complex query can be written using that.
And some says postgres9.5 and above support merge statement. since we are using postgres 10 tried to use same oracle query in postgres but recieved ERROR: syntax error at or near "MERGE"
Any help is highly appreciated.
You don't need an "UPSERT" as you are not doing an INSERT, so a regular UPDATE is enough:
update act_pack C
SET C.md = D.md,
C.hd = D.h
from (
SELECT A.jid, A.pid, B.pcode, B.mc, A.md, A.hd
FROM s.act_pack A
INNER JOIN s.act_pack B
ON A.pid = B.pid
AND A.pcode = B.mc
AND (A.hd <> B.hd OR A.md<> B.md)
) d
where C.pid = D.pid
AND C.pcode = D.pcode
AND C.jid = D.jid
This is a direct "translation" of your code. But the fact that the same table is used three times is a bit strange. But without more information it's hard to know where exactly this could be made more efficient.

DB2 Query : insert data in history table if not exists already

I have History table and transaction table.....and reference table...
If status in reference table is CLOSE then take those record verify in History table if not there insert from transaction table..... wiring query like this .... checking better one... please advice.. this query can be used for huge data ?
INSERT INTO LIB1.HIST_TBL
( SELECT R.ACCT, R.STATUS, R.DATE FROM
LIB2.HIST_TBL R JOIN LIB1.REF_TBL C
ON R.ACCT = C.ACCT WHERE C.STATUS = '5'
AND R.ACCT NOT IN
(SELECT ACTNO FROM LIB1.HIST_TBL)) ;
If you're on a current release of DB2 for i, take a look at the MERGE statement
MERGE INTO hist_tbl H
USING (SELECT * FROM ref_tbl R
WHERE r.status = 'S')
ON h.actno = r.actno
WHEN NOT MATCHED THEN
INSERT (actno,histcol2, histcol3) VALUES (r.actno,r.refcol2,r.refcol3)
--if needed
WHEN MATCHED
UPDATE SET (actno,histcol2, histcol3) = (r.actno,r.refcol2,r.refcol3)

Use python to execute line in postgresql

I have imported one shapefile named tc_bf25 using qgis, and the following is my python script typed in pyscripter,
import sys
import psycopg2
conn = psycopg2.connect("dbname = 'routing_template' user = 'postgres' host = 'localhost' password = '****'")
cur = conn.cursor()
query = """
ALTER TABLE tc_bf25 ADD COLUMN source integer;
ALTER TABLE tc_bf25 ADD COLUMN target integer;
SELECT assign_vertex_id('tc_bf25', 0.0001, 'the_geom', 'gid')
;"""
cur.execute(query)
query = """
CREATE OR REPLACE VIEW tc_bf25_ext AS
SELECT *, startpoint(the_geom), endpoint(the_geom)
FROM tc_bf25
;"""
cur.execute(query)
query = """
CREATE TABLE node1 AS
SELECT row_number() OVER (ORDER BY foo.p)::integer AS id,
foo.p AS the_geom
FROM (
SELECT DISTINCT tc_bf25_ext.startpoint AS p FROM tc_bf25_ext
UNION
SELECT DISTINCT tc_bf25_ext.endpoint AS p FROM tc_bf25_ext
) foo
GROUP BY foo.p
;"""
cur.execute(query)
query = """
CREATE TABLE network1 AS
SELECT a.*, b.id as start_id, c.id as end_id
FROM tc_bf25_ext AS a
JOIN node AS b ON a.startpoint = b.the_geom
JOIN node AS c ON a.endpoint = c.the_geom
;"""
cur.execute(query)
query = """
ALTER TABLE network1 ADD COLUMN shape_leng double precision;
UPDATE network1 SET shape_leng = length(the_geom)
;"""
cur.execute(query)
I got the error at the second cur.execute(query),
But I go to pgAdmin to check result, even though no error occurs, the first cur.execute(query) didn't add new columns in my table.
What mistake did I make? And how to fix it?
I am working with postgresql 8.4, python 2.7.6 under Windows 8.1 x64.
When using psycopg2, autocommit is set to False by default. The first two statements both refer to table tc_bf25, but the first statement makes an uncommitted change to the table. So try running conn.commit() between statements to see if this resolves the issue
You should run each statement individually. Do not combine multiple statements into a semicolon separated series and run them all at one. It makes error handling and fetching of results much harder.
If you still have the problem once you've made that change, show the exact statement you're having the problem with.
Just to add to #Talvalin you can enable auto-commit by adding
psycopg2.connect("dbname='mydb',user='postgres',host ='localhost',password = '****'")
conn.autocommit = True
after you connect to your database using psycopg2

Metadata about a column in SQL Server 2008 R2?

I'm trying to figure out a way to store metadata about a column without repeating myself.
I'm currently working on a generic dimension loading SSIS package that will handle all my dimensions. It currently does :
Create a temporary table identical to the given table name in parameters (this is a generic stored procedure that receive the table name as parameter, and then do : select top 0 * into ##[INSERT ORIGINAL TABLE NAME HERE] from [INSERT ORIGINAL TABLE NAME HERE]).
==> Here we insert custom code for this particular dimension that will first query the data from a datasource and get my delta, then transform the data and finally loads it into my temporary table.
Merge the temporary table into my original table with a T-SQL MERGE, taking care of type1 and type2 fields accordingly.
My problem right now is that I have to maintain a table with all the fields in it to store a metadata to tell my scripts if this particular field is type1 or type2... this is nonsense, I can get the same data (minus type1/type2) from sys.columns/sys.types.
I was ultimately thinking about renaming my fields to include their type in it, such as :
FirstName_T2, LastName_T2, Sex_T1 (well, I know this can be type2, let's not fall into that debate here).
What do you guyz would do with that? My solution (using a table with that metadata) is currently in place and working, but it's obvious that repeating myself from the systables to a custom table is nonsense, just for a simple type1/type2 info.
UPDATE: I also thought about creating user defined types like varchar => t1_varchar, t2_varchar, etc. This sounds like something a bit sluggy too...
Everything you need should already be in INFORMATION_SCHEMA.COLUMNS
I can't follow your thinking of not using provided tables/views...
Edit: As scarpacci mentioned, this somewhat portable if needed.
I know this is bad, but I will post an answer to my own question... Thanks to GBN for the help tho!
I am now storing "flags" in the "description" field of my columns. I, for example, can store a flag this way : "TYPE_2_DATA".
Then, I use this query to get the flag back for each and every column :
select columns.name as [column_name]
,types.name as [type_name]
,extended_properties.value as [column_flags]
from sys.columns
inner join sys.types
on columns.system_type_id = types.system_type_id
left join sys.extended_properties
on extended_properties.major_id = columns.object_id
and extended_properties.minor_id = columns.column_id
and extended_properties.name = 'MS_Description'
where object_id = ( select id from sys.sysobjects where name = 'DimDivision' )
and is_identity = 0
order by column_id
Now I can store metadata about columns without having to create a separate table. I use what's already in place and I don't repeat myself. I'm not sure this is the best possible solution yet, but it works and is far better than duplicating information.
In the future, I will be able to use this field to store more metadata, where as : "TYPE_2_DATA|ANOTHER_FLAG|ETC|OH BOY!".
UPDATE :
I now store the information in separate extended properties. You can manage extended properties using sp_addextendedproperty and sp_updateextendedproperty stored procedures. I have created a simple store procedure that help me to update those values regardless if they currently exist or not :
create procedure [dbo].[UpdateSCDType]
#tablename nvarchar(50),
#fieldname nvarchar(50),
#scdtype char(1),
#dbschema nvarchar(25) = 'dbo'
as
begin
declare #already_exists int;
if ( #scdtype = '1' or #scdtype = '2' )
begin
select #already_exists = count(1)
from sys.columns
inner join sys.extended_properties
on extended_properties.major_id = columns.object_id
and extended_properties.minor_id = columns.column_id
and extended_properties.name = 'ScdType'
where object_id = (select sysobjects.id from sys.sysobjects where sysobjects.name = #tablename)
and columns.name = #fieldname
if ( #already_exists = 0 )
begin
exec sys.sp_addextendedproperty
#name = N'Scd_Type',
#value = #scdtype,
#level0type = N'SCHEMA',
#level0name = #dbschema,
#level1type = N'TABLE',
#level1name = #tablename,
#level2type = N'COLUMN',
#level2name = #fieldname
end
else
begin
exec sys.sp_updateextendedproperty
#name = N'Scd_Type',
#value = #scdtype,
#level0type = N'SCHEMA',
#level0name = #dbschema,
#level1type = N'TABLE',
#level1name = #tablename,
#level2type = N'COLUMN',
#level2name = #fieldname
end
end
end
Thanks again