We are trying to implement a password interval, if there is one.
If sm_Setting(PasswordExpireDays) has a value, we use it. If not, continue on
CREATE Procedure user_password_date_interval_check
#ua_pk uniqueidentifier
AS
DECLARE #PasswordExpireDays int
SET #PasswordExpireDays = 0
SELECT
sm_Setting, sm_Value
FROM
Setting_Misc AS sm
INNER JOIN
Syndicates As syn ON sm.syn_fk = syn.syn_pk
INNER JOIN
Company As c ON c.syn_fk = syn.syn_pk
INNER JOIN
User_Accounts As ua ON ua.c_fk = c.c_pk
WHERE
sm.sm_Setting = 'PasswordExpireDays'
THEN sm.sm_Value = #PasswordExpireDays
I'm having issues with the WHERE clause. I have tried CASE. Bottom line is, this row (based on a PK and Setting), I want to grab the value from the Value column.
CREATE Procedure user_password_date_interval_check
#ua_pk uniqueidentifier
AS
DECLARE #PasswordExpireDays int
SELECT
--sm_Setting,
#PasswordExpireDays =COALESCE(sm_Value,0)
FROM
Setting_Misc AS sm
INNER JOIN
Syndicates As syn
ON sm.syn_fk = syn.syn_pk
INNER JOIN
Company As c
ON c.syn_fk = syn.syn_pk
INNER JOIN
User_Accounts As ua
ON ua.c_fk = c.c_pk
WHERE sm.sm_Setting = 'PasswordExpireDays'
--#PasswordExpireDays is either default 0 or the value from the table if not null.
Each of our clients has a database with their own data. Each database should have exactly the same structure. How can I find columns whose datatype has been changed, where the table name and column name is the same but the datatype is not? Is there an SQL query that can do this?
Take snapshots of the schemas and use REDGATE's SQL Compare utility.
Or export the schemas to text and use BeyondCompare
If both databases can be restored to the same server, you can compare the two sets of system catalog views to determine the differences:
SELECT
TableName = t.name,
ColumnName = c.name,
TypeName = ty.name,
TableName2 = t2.name,
ColumnName2 = c2.name,
TypeName2 = ty2.name
FROM DB1.sys.columns c
INNER JOIN DB1.sys.tables t ON c.object_id = t.object_id
INNER JOIN DB1.sys.types ty ON c.system_type_id = ty.system_type_id
INNER JOIN DB2.sys.tables t2 ON t.name = t2.Name
INNER JOIN DB2.sys.columns c2 ON c2.object_id = t2.object_id AND c.name = c2.name
INNER JOIN DB2.sys.types ty2 ON c2.system_type_id = ty2.system_type_id
WHERE
c.system_type_id <> c2.system_type_id
Of course, you can add more columns from the sys.columns catalog view, e.g. precision and scale for types like DECIMAL(18,2), or max_length for string-based types (like VARCHAR(50) etc.) - adapt this base query as needed
The Atlantis SchemaInspector is good tool for this purpose.
EDIT:
If you want SQL query, you need the available both databases in one query.
So the databases must be on one sql server instance OR the sql server instances must are available as linked server.
Query:
SELECT
*
/* source database >>> */
FROM [SourceDatabase].[sys].[schemas] AS S_A
INNER JOIN [SourceDatabase].[sys].[objects] AS O_A
ON [O_A].[schema_id] = [S_A].[schema_id]
INNER JOIN [SourceDatabase].[sys].[columns] AS C_A
ON [C_A].[object_id] = [O_A].[object_id]
/* <<< source database */
/* target database >>> */
LEFT JOIN [TargetDatabase].[sys].[schemas] AS S_B
ON [S_B].[name] = [S_A].[name]
LEFT JOIN [TargetDatabase].[sys].[objects] AS O_B
ON [O_B].[schema_id] = [S_B].[schema_id]
AND [O_B].[name] = [O_A].[name]
LEFT JOIN [TargetDatabase].[sys].[columns] AS C_B
ON [C_B].[object_id] = [O_B].[object_id]
AND [C_B].[name] = [C_A].[name]
/* <<< target database */
WHERE [C_B].[column_id] IS NULL
OR [C_B].[system_type_id] <> [C_A].[system_type_id]
I've built a tool that uses table foreign keys but I'd like to extend it to support views.
In SQL Server 2008 and above, assuming you are only interested in dependencies within the same database, you can use the following query to determine all of the tables, views, and functions referenced within each view:
;WITH x AS
(
SELECT
v = QUOTENAME(OBJECT_SCHEMA_NAME(d.referencing_id))
+ '.' + QUOTENAME(OBJECT_NAME(d.referencing_id)),
t = QUOTENAME(OBJECT_SCHEMA_NAME(d.referenced_id))
+ '.' + QUOTENAME(OBJECT_NAME(d.referenced_id)),
td = o2.type_desc
FROM sys.sql_expression_dependencies AS d
INNER JOIN sys.objects AS o1
ON d.referencing_id = o1.[object_id]
INNER JOIN sys.objects AS o2
ON d.referenced_id = o2.[object_id]
WHERE o1.type_desc = 'VIEW'
)
SELECT [View] = v, Referenced_Object = t, [Type] = td
FROM x
GROUP BY v, t, td
ORDER BY v, t;
I have to get the Table and Column name of the Foreign keys on Oracle, can anybody confirm the following statement?
SELECT a.table_name AS TableWithForeignKey, b.column_name AS ForeignKeyColumn
FROM user_constraints a INNER JOIN user_cons_columns b
ON (a.constraint_name = b.constraint_name) AND (a.table_name = b.table_name)
and a.constraint_type = 'R'
The Part I'm not sure about is the INNER JOIN Part (after ON):
(a.constraint_name = b.constraint_name) AND (a.table_name = b.table_name)
As I couldn't find something like constraints_ID, is this enought to match 1:1 rows from both tables user_constraints and user_cons_columns
Thank you.
I use the
a.constraint_name = b.constraint_name
for joining the 2 views
so, I think it's OK
When programming a large transaction (lots of inserts, deletes, updates) and thereby violating a constraint in Informix (v10, but should apply to other versions too) I get a not very helpful message saying, for example, I violated constraint r190_710. How can I find out which table(s) and key(s) are covered by a certain constraint I know only the name of?
Tony Andrews suggested (pointing to a different end-point for the URL):
From Informix Guide to SQL: Reference it appears you should look at the system catalog tables SYSCONSTRAINTS and SYSINDICES.
The Informix system catalog is described in that manual.
The SysConstraints table is the starting point for analyzing a constraint, most certainly; you find the constraint name in that table, and from there you can find out the other details.
However, you also have to look at other tables, and not just (or even directly) SysIndices.
For example, I have a lot of NOT NULL constraints on the tables in my database. For those, the constraint type is 'N' and there is no need to look elsewhere for more information.
A constraint type of 'P' indicates a primary key; that would need more analysis via the SysIndexes view or SysIndices table. Similarly, a constraint type of 'U' indicates a unique constraint and needs extra information from the SysIndexes view or SysIndices table.
A constraint type of 'C' indicates a check constraint; the text (and binary compiled form) of the constraint is found in the SysChecks table (with types 'T' and 'B' for the data; the data is more or less encoded with Base-64, though without the '=' padding at the end and using different characters for 62 and 63).
Finally, a constraint type of 'R' indicates a referential integrity constraint. You use the SysReferences table to find out which table is referenced, and you use SysIndexes or SysIndices to establish which indexes on the referencing and referenced tables are used, and from that you can discover the relevant columns. This can get quite hairy!
Columns in a table with a constraint on them
SELECT
a.tabname, b.constrname, d.colname
FROM
systables a, sysconstraints b, sysindexes c, syscolumns d
WHERE
a.tabname = 'your_table_name_here'
AND
b.tabid = a.tabid
AND
c.idxname = b.idxname
AND
d.tabid = a.tabid
AND
(
d.colno = c.part1 or
d.colno = c.part2 or
d.colno = c.part3 or
d.colno = c.part4 or
d.colno = c.part5 or
d.colno = c.part6 or
d.colno = c.part7 or
d.colno = c.part8 or
d.colno = c.part9 or
d.colno = c.part10 or
d.colno = c.part11 or
d.colno = c.part12 or
d.colno = c.part13 or
d.colno = c.part14 or
d.colno = c.part15 or
d.colno = c.part16
)
ORDER BY
a.tabname,
b.constrname,
d.colname
I have been using the following query to get more information about the different types of constraints.
It's based on some spelunking in the system tables and several explanations about the system catalog.
sysconstraints.constrtype indicates the type of the constraint:
P = Primary key
U = Unique key / Alternate key
N = Not null
C = Check
R = Reference / Foreign key
select
tab.tabname,
constr.*,
chk.*,
c1.colname col1,
c2.colname col2,
c3.colname col3,
c4.colname col4,
c5.colname col5
from sysconstraints constr
join systables tab on tab.tabid = constr.tabid
left outer join syschecks chk on chk.constrid = constr.constrid and chk.type = 'T'
left outer join sysindexes i on i.idxname = constr.idxname
left outer join syscolumns c1 on c1.tabid = tab.tabid and c1.colno = abs(i.part1)
left outer join syscolumns c2 on c2.tabid = tab.tabid and c2.colno = abs(i.part2)
left outer join syscolumns c3 on c3.tabid = tab.tabid and c3.colno = abs(i.part3)
left outer join syscolumns c4 on c4.tabid = tab.tabid and c4.colno = abs(i.part4)
left outer join syscolumns c5 on c5.tabid = tab.tabid and c5.colno = abs(i.part5)
where constr.constrname = 'your constraint name'
to get the table affected by the constraint "r190_710":
select TABNAME from SYSTABLES where TABID IN
(select TABID from sysconstraints where CONSTRID IN
(select CONSTRID from sysreferences where PTABID IN
(select TABID from sysconstraints where CONSTRNAME= "r190_710" )
)
);
From Informix Guide to SQL: Reference it appears you should look at the system catalog tables SYSCONSTRAINTS and SYSINDICES.
From surfing at www.iiug.org (International Informix Users Group) i found the not-so-easy solution.
(1) Get referential constraint data from the constraint name (you can get all constraints for a table by replacing "AND sc.constrname = ?" by "AND st.tabname MATCHES ?"). This statement selects some more fields than necessary here because they might be interesting in other situations.
SELECT si.part1, si.part2, si.part3, si.part4, si.part5,
si.part6, si.part7, si.part8, si.part9, si.part10,
si.part11, si.part12, si.part13, si.part14, si.part15, si.part16,
st.tabname, rt.tabname as reftable, sr.primary as primconstr,
sr.delrule, sc.constrid, sc.constrname, sc.constrtype,
si.idxname, si.tabid as tabid, rc.tabid as rtabid
FROM 'informix'.systables st, 'informix'.sysconstraints sc,
'informix'.sysindexes si, 'informix'.sysreferences sr,
'informix'.systables rt, 'informix'.sysconstraints rc
WHERE st.tabid = sc.tabid
AND st.tabtype != 'Q'
AND st.tabname NOT MATCHES 'cdr_deltab_[0-9][0-9][0-9][0-9][0-9][0-9]*'
AND rt.tabid = sr.ptabid
AND rc.tabid = sr.ptabid
AND sc.constrid = sr.constrid
AND sc.tabid = si.tabid
AND sc.idxname = si.idxname
AND sc.constrtype = 'R'
AND sc.constrname = ?
AND sr.primary = rc.constrid
ORDER BY si.tabid, sc.constrname
(2) Use the part1-part16 to determine which column is affected by the constraint: the part[n] containing a value different from 0 contains the column number of the used column. Use (3) to find the name of the column.
If constrtype is 'R' (referencing) use the following statement to find the parts of the referencing table:
SELECT part1, part2, part3, part4, part5, part6, part7, part8,
part9, part10, part11, part12, part13, part14, part15, part16
FROM 'informix'.sysindexes si, 'informix'.sysconstraints sc
WHERE si.tabid = sc.tabid
AND si.idxname = sc.idxname
AND sc.constrid = ? -- primconstr from (1)
(3) the tabid and rtabid (for referencing constraints) from (1) can now be used to get the columns of the tables like that:
SELECT colno, colname
FROM 'informix'.syscolumns
WHERE tabid = ? -- tabid(for referenced) or rtabid(for referencing) from (1)
AND colno = ? -- via parts from (1) and (2)
ORDER BY colno
(4) If the constrtype is 'C', then get the check information like this:
SELECT type, seqno, checktext
FROM 'informix'.syschecks
WHERE constrid = ? -- constrid from (1)
Quite hairy indeed
If your constraint is named constraint_c6, here's how to dump its definition (well sort-of, you still need to concatenate the rows, as they'll be separated by whitespace):
OUTPUT TO '/tmp/constraint_c6.sql' WITHOUT HEADINGS
SELECT ch.checktext
FROM syschecks ch, sysconstraints co
WHERE ch.constrid = co.constrid
AND ch.type = 'T' -- text lines only
AND co.constrname = 'constraint_c6'
ORDER BY ch.seqno;