Discussione:
Vista di sistema per chiavi primarie
(troppo vecchio per rispondere)
Maurizio
2005-10-19 09:44:20 UTC
Permalink
ciao a tutti, ho da porvi il seguente quesito:
esiste in SQL Server una vista di sistema (tipo
nome_db.INFORMATION_SCHEMA.COLUMNS) per ricavare le chiavi primarie di
una tabella?

Spero nel vostro aiuto...

CIAO!!!
Lorenzo Benaglia
2005-10-19 09:48:09 UTC
Permalink
Post by Maurizio
esiste in SQL Server una vista di sistema (tipo
nome_db.INFORMATION_SCHEMA.COLUMNS) per ricavare le chiavi primarie di
una tabella?
Ciao Maurizio,

prova a leggere il seguente post:
http://groups.google.it/group/microsoft.public.it.sql/msg/3fe07dd508b873c6

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org
Maurizio
2005-10-19 09:55:23 UTC
Permalink
intanto grazie mille per la risposta!!!
vado a vedere immediatamente il post...

se avrò ancora dei problemi posterò nuovamente...

GRAZIE MILLE!!!!
Maurizio
2005-10-19 10:49:32 UTC
Permalink
Perfetto...funziona!!!
grazie!!!

P.S. sono solo un po' in difficoltà con le chiavi esterne...
vi posto la mia query...potreste dirmi come devo modificarla per
recuperare se un campo è chiave esterna???

SELECT
E.[TableName],
A.[AttributeTypeId],
A.[AttributeTypeName],
C.[COLUMN_NAME] AS FieldName,
C.[ORDINAL_POSITION] AS ColumnNo,
CASE C.[IS_NULLABLE]
WHEN 'NO' THEN 0
ELSE 1
END AS IsNullable,
CASE ccu.[COLUMN_NAME]
WHEN C.[COLUMN_NAME] THEN 1
ELSE 0
END AS IsPrimaryKey
FROM
Traq_03.INFORMATION_SCHEMA.COLUMNS C
INNER JOIN
Traq_03_Base..Meta_Entities E ON C.TABLE_NAME = E.[TableName]
INNER JOIN
Traq_03_Base..Meta_AttributeTypes A ON C.DATA_TYPE =
A.[AttributeTypeName]
INNER JOIN
Traq_03.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu ON
C.TABLE_NAME = ccu.TABLE_NAME
INNER JOIN
Traq_03.INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON
ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE
tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
Roberto Sartori
2005-10-19 11:10:34 UTC
Permalink
Guarda il post "Vincoli Foreign Key" qua sotto ...

Ciao
Roberto

"Maurizio" <***@uniteambo.it> ha scritto nel messaggio news:***@g44g2000cwa.googlegroups.com...
Perfetto...funziona!!!
grazie!!!

P.S. sono solo un po' in difficoltà con le chiavi esterne...
vi posto la mia query...potreste dirmi come devo modificarla per
recuperare se un campo è chiave esterna???

SELECT
E.[TableName],
A.[AttributeTypeId],
A.[AttributeTypeName],
C.[COLUMN_NAME] AS FieldName,
C.[ORDINAL_POSITION] AS ColumnNo,
CASE C.[IS_NULLABLE]
WHEN 'NO' THEN 0
ELSE 1
END AS IsNullable,
CASE ccu.[COLUMN_NAME]
WHEN C.[COLUMN_NAME] THEN 1
ELSE 0
END AS IsPrimaryKey
FROM
Traq_03.INFORMATION_SCHEMA.COLUMNS C
INNER JOIN
Traq_03_Base..Meta_Entities E ON C.TABLE_NAME = E.[TableName]
INNER JOIN
Traq_03_Base..Meta_AttributeTypes A ON C.DATA_TYPE =
A.[AttributeTypeName]
INNER JOIN
Traq_03.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu ON
C.TABLE_NAME = ccu.TABLE_NAME
INNER JOIN
Traq_03.INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON
ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE
tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
Maurizio
2005-10-19 12:02:19 UTC
Permalink
ti ringrazio per la risposta...però non so come integrare il codice
dell'altra discussione...sono in difficoltà perchè non vengono usate
le viste di sistema... :-)
Roberto Sartori
2005-10-19 12:42:42 UTC
Permalink
Per quello che ho visto, usando le viste di
sistema puoi ottenere informazioni per quanto riguarda
la presenza dei vincoli di chiave esterna,
ma non sui loro dettagli (tabelle e campi coinvolti).
Per questo devi usare direttamente le tabelle di sistema.

Resto in attesa che qualcuno mi smentisca :-)

Ciao
Roberto

"Maurizio" <***@uniteambo.it> wrote in message news:***@g43g2000cwa.googlegroups.com...
ti ringrazio per la risposta...però non so come integrare il codice
dell'altra discussione...sono in difficoltà perchè non vengono usate
le viste di sistema... :-)
AlessandroD
2005-10-19 12:59:23 UTC
Permalink
Post by Roberto Sartori
Per quello che ho visto, usando le viste di
sistema puoi ottenere informazioni per quanto riguarda
la presenza dei vincoli di chiave esterna,
ma non sui loro dettagli (tabelle e campi coinvolti).
Per questo devi usare direttamente le tabelle di sistema.
Resto in attesa che qualcuno mi smentisca :-)
In verità ho visto che combinando queste viste standard:

INFORMATION_SCHEMA.TABLE_CONSTRAINTS
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE

Sei in grado di ottenere anche le colonne coinvolte, il problema è che manca
la corrispondenza colonna per colonna, il legame è solo tra i nomi dei
constraint.
Cioè sai che il constraint PippoPK è legato al constraint PlutoFK, ma non
arrivi ad associare anche i singoli campi, puoi avere al massimo l'elenco
dei campi usati dai due constraint, ma non come sono legati tra di loro.
Peccato, anche perché così "castrata" l'informazione è poco utile.
Ciao, Alessandro
Maurizio
2005-10-19 14:02:52 UTC
Permalink
Nessuno riuscirebbe a darmi una mano per modificare la query che ho
incollato sopra in modo tale da avere (per ogni riga) sia
l'informazione se il campo è chiave primaria (già questo la query lo
fa) e se è chiave esterna?

GRAZIE!!!
Post by Maurizio
Post by Roberto Sartori
Per quello che ho visto, usando le viste di
sistema puoi ottenere informazioni per quanto riguarda
la presenza dei vincoli di chiave esterna,
ma non sui loro dettagli (tabelle e campi coinvolti).
Per questo devi usare direttamente le tabelle di sistema.
Resto in attesa che qualcuno mi smentisca :-)
INFORMATION_SCHEMA.TABLE_CONSTRAINTS
INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
Sei in grado di ottenere anche le colonne coinvolte, il problema è che manca
la corrispondenza colonna per colonna, il legame è solo tra i nomi dei
constraint.
Cioè sai che il constraint PippoPK è legato al constraint PlutoFK, ma non
arrivi ad associare anche i singoli campi, puoi avere al massimo l'elenco
dei campi usati dai due constraint, ma non come sono legati tra di loro.
Peccato, anche perché così "castrata" l'informazione è poco utile.
Ciao, Alessandro
AlessandroD
2005-10-19 14:30:32 UTC
Permalink
Post by Maurizio
Nessuno riuscirebbe a darmi una mano per modificare la query che ho
incollato sopra in modo tale da avere (per ogni riga) sia
l'informazione se il campo è chiave primaria (già questo la query lo
fa) e se è chiave esterna?
Prova così:

SELECT
E.[TableName],
A.[AttributeTypeId],
A.[AttributeTypeName],
C.[COLUMN_NAME] AS FieldName,
C.[ORDINAL_POSITION] AS ColumnNo,
CASE C.[IS_NULLABLE]
WHEN 'NO' THEN 0
ELSE 1
END AS IsNullable,
CASE ccu.[COLUMN_NAME]
WHEN C.[COLUMN_NAME] THEN 1
ELSE 0
END AS IsPrimaryKey,
CASE WHEN rc.UNIQUE_CONSTRAINT_NAME IS NULL THEN 0 ELSE 1 END AS
IsForeignKey
FROM
Traq_03.INFORMATION_SCHEMA.COLUMNS C
INNER JOIN
Traq_03_Base..Meta_Entities E ON C.TABLE_NAME = E.[TableName]
INNER JOIN
Traq_03_Base..Meta_AttributeTypes A ON C.DATA_TYPE =
A.[AttributeTypeName]
INNER JOIN
Traq_03.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu ON
C.TABLE_NAME = ccu.TABLE_NAME
INNER JOIN
Traq_03.INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON
ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
LEFT JOIN
Traq_03.INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON
tc.CONSTRAINT_NAME= rc.UNIQUE_CONSTRAINT_NAME
WHERE
tc.CONSTRAINT_TYPE = 'PRIMARY KEY'

Praticamente ho aggiunto in fondo una left join con la vista
REFERENTIAL_CONSTRAINTS per vedere se il constraint di chiave primaria è
per caso usato in un constraint riferito ad una chiave esterna, se è
presente allora il nuovo campo calcolato IsForeignKey vale 1, altrimenti 0.
Ciao, Alessandro
Maurizio
2005-10-20 08:05:57 UTC
Permalink
Grazie per il codice...purtroppo però non funziona :-(
al posto di ritornarmi 327 righe me ne ritorna 768...
All'inizio avevo provato così:

SELECT
E.[TableName],
A.[AttributeTypeName],
C.[COLUMN_NAME] AS FieldName,
C.[ORDINAL_POSITION] AS ColumnNo,
CASE C.[IS_NULLABLE]
WHEN 'NO' THEN 0
ELSE 1
END AS IsNullable,
CASE ccu.[COLUMN_NAME]
WHEN C.[COLUMN_NAME] THEN 1
ELSE 0
END AS IsPrimaryKey,
CASE tc.CONSTRAINT_TYPE
WHEN 'FOREIGN KEY' THEN 1
ELSE 0
END AS IsForeignKey
FROM
Traq_03.INFORMATION_SCHEMA.COLUMNS C
INNER JOIN
Traq_03_Base..Meta_Entities E ON C.TABLE_NAME = E.[TableName]
INNER JOIN
Traq_03_Base..Meta_AttributeTypes A ON C.DATA_TYPE =
A.[AttributeTypeName]
INNER JOIN
Traq_03.INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu ON
C.TABLE_NAME = ccu.TABLE_NAME
INNER JOIN
Traq_03.INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON
ccu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE
tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
OR
tc.CONSTRAINT_TYPE = 'FOREIGN KEY'

però mi ritornava addirittura 995 righe...sono veramente depresso...ma
esisterà un modo???

praticamente la query dovrebbe fare questo: se è chiave primaria metti
la colonna IsPrimaryKey per quella riga a 1 (e IsForeignKey a 0) e
viceversa, così da avere "MioCampo", 1 (IsPrimaryKey),
0(IsForeignKey).

nelle altre query mi ritorna questo tipo di risultato:
"Campo1", 1, 0
"Campo1", 0, 1
"Campo1", 0, 0

in questo caso dovrei avere una sola riga così: "Campo1", 1, 1

:-(

Aiuto! :-P

Comunque grazie per tutte le risposte ricevute...ne aspetto altre :-P

:-)
AlessandroD
2005-10-20 16:39:19 UTC
Permalink
Post by Maurizio
Grazie per il codice...purtroppo però non funziona :-(
al posto di ritornarmi 327 righe me ne ritorna 768...
Allora, io ho inteso che ti serviva sapere quando una chiave primaria era
anche usata come chiave esterna, mentre da quello che dici questa
informazione non ti serve.
Poi nella tua query fai dei join non completi (solo su tabella e non su
tabella + colonna) che causano il moltiplicarsi delle righe.
Visto che io non possiedo le tue tabelle Meta*, ho fatto una prova più
generica, e con questa query credo di aver ottenuto quello che ti serve, ora
basta che tu ci aggiungi i join alle tue tabelle e dovresti essere apposto:


SELECT
C.TABLE_NAME,
C.[COLUMN_NAME] AS FieldName,
C.[ORDINAL_POSITION] AS ColumnNo,
CASE C.[IS_NULLABLE] WHEN 'NO' THEN 0 ELSE 1 END AS IsNullable,
CASE tc.CONSTRAINT_TYPE WHEN 'PRIMARY KEY' THEN 1 ELSE 0 END AS
IsPrimaryKey,
CASE tc.CONSTRAINT_TYPE WHEN 'FOREIGN KEY' THEN 1 ELSE 0 END AS
IsForeignKey
FROM
INFORMATION_SCHEMA.COLUMNS C INNER JOIN
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
ON C.TABLE_NAME = ccu.TABLE_NAME and C.COLUMN_NAME= ccu.COLUMN_NAME
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON ccu.TABLE_NAME= tc.TABLE_NAME and ccu.CONSTRAINT_NAME =
tc.CONSTRAINT_NAME
WHERE
tc.CONSTRAINT_TYPE in ('PRIMARY KEY', 'FOREIGN KEY')

Ciao, Alessandro

Continua a leggere su narkive:
Loading...