Trouver la clé primaire par programmation?

tout est dit dans le titre.

Je n’ai pas vu ça :

  • ni dans “Lire Propriétés Champ” (en bouclant éventuellement sur tous les champs de la Table)
  • ni dans “Lire Propriétés Table”.

Peut-être avec ORDA et l’attribut __KEY ?

Bonjour Luc,

2 moyens:

Patrick

<code 4D>
// BASE_numeroClePrimaire ( table ) -> numéro du champ clé primaire (0 si aucun)

C_ENTIER LONG($0;$1;$table;$champClePrimaire;$possedeCle)

$table:=$1

Début SQL
SELECT TABLE_ID
FROM _USER_CONSTRAINTS
WHERE TABLE_ID=:$table
AND CONSTRAINT_TYPE=‘P’
INTO :$possedeCle;
Fin SQL

Si ($possedeCle=0)

$champClePrimaire:=0

Sinon

Début SQL
	SELECT COLUMN_ID
	FROM _USER_CONS_COLUMNS
	WHERE TABLE_ID= :$table
	INTO :$champClePrimaire;
Fin SQL

Fin de si

$0:=$champClePrimaire

</code 4D>

Bonjour Mimosa,

c’est carrément parfait !
rien à ajouter, sauf … merci

merci Patrick également,
j’ai lu ton post un peu plus tard que celui de Mimosa, mais l’article de la KB est du même accabit (via SQL).

une variante :

http://forums.4d.com/4DBB_Main/x_User/3906/files/25254672.7z

<code 4D>
// La méthode Get_Primary_Key retourne le numéro du champ qui est la PK
//
// #SYNTAX: $L_num_champ:=Get_Primary_Key(table num)
// #PARAMETERS:
// $0 Long : numéro du champ PK
// $1 Long : numero table

// #DATE CREATION: 21/10/2014 #AUTHOR: Ortwin Zillgen http://dddd.mettre.de/primaryKeyTT.shtml?from=forum
// #DATE MODIFICATION: 00/00/0000
// #NOTE:
//
// #HEADER VERSION: 2

C_LONGINT($0;$primary_key_field_id_l) // Le numéro du champ qui contient la PK
C_LONGINT($table_id_l;$1) // Un numéro de table valide
$table_id_l:=$1

$primary_key_field_id_l:=0

If (Is table number valid($table_id_l))

C_TEXT($constrainID)
Begin SQL
	
	  SELECT CONSTRAINT_ID
	  FROM _USER_CONSTRAINTS
	  WHERE TABLE_ID = :$table_id_l AND CONSTRAINT_TYPE = 'P'
	  INTO :$constrainID;
	 
	  SELECT COLUMN_ID
	  FROM _USER_CONS_COLUMNS
	  WHERE CONSTRAINT_ID = :$constrainID
	  INTO :$primary_key_field_id_l;
End SQL

End if

$0:=$primary_key_field_id_l

// EOM

</code 4D>

Une remarque, une PK peut être théoriquement constituée de http://forums.4d.com/Post/FR/12643175/1/14402984#14397023plusieurs champs> ; cela dit, en pratique, je maîtrise pas donc je fais pas…
D’autre part, sql ou EXPORTER STRUCTURE = requête au serveur. Je pense donc préférable de monter un tableau des PK à l’ouverture, plutôt qu’interroger le serveur à chaque fois qu’on a besoin de la clé primaire d’une table ; en ce sens, EXPORTER STRUCTURE me semble préférable car on y trouve cette information http://forums.4d.com/Post/FR/24944477/0/0/“mais pas que”>.

ce sont des solutions qui fonctionnent, mais ne serait-ce pas plus simple d’obtenir cette information dans la commande “Lire propriétés Champ” , surtout que les clés primaires sont devenues quasi-obligatoires depuis la v15 ?
En général on ne change pas la PK d’une table en cours d’exploitation d’une base.

@Arnaud : les PK constituées de plusieurs champs sont traitées dans la méthode de la KB citée plus haut.
Mais pour avoir eu à en utiliser pour accéder à certaines BDD, je ne fais pas non plus.

: Luc STELL

ne serait-ce pas plus simple d’obtenir cette information dans la
commande “Lire propriétés Champ”
lire propriété table, comme la clé peut être constituée de plusieurs champs - même si on ne le fait pas :wink:

les PK constituées de plusieurs champs sont traitées dans la méthode
de la KB citée plus haut.
Elle est pas “décisive”, cette NT : on a ça 3 ans avant sur 4dbb, 2 requêtes quand on peut en faire une, et ça fait partie des bouts de code dont on se demande pourquoi il n’est pas en exemple http://doc.4d.com/4Dv17/4D/17/Tables-systeme.300-3786652.fr.htmldans une doc SQL> qui en manque cruellement !

Au risque d’insister, je pense qu’il y a plus d’avenir à exploiter structure-en-xml que structure-en-sql. SQL est plus un greffon qu’un fondement de 4D, orda est arrivé et ça ne m’étonnerait guère que structure-en-xml devienne structure-en-objet.

: Arnaud DE MONTARD

orda est arrivé et ça ne m’étonnerait guère que structure-en-xml
devienne structure-en-objet.
Oh oui, oh oui !!!

structure-en-xml devienne structure-en-objet
En attendant on le fait soi-même, y compris https://blog.4d.com/detailed-analysis-database-structure/chez 4d> :wink:

Exactement et c’est cela que j’ai intégré dans xxxx :wink:

Oui, j’ai regardé les entrailles du sanglier :wink: . Je préfère mon approche, convertir d’emblée tout le xml en objet : quand je fais du xml je passe mon temps dans la doc.

ben si tu regardes bien, c’est ce qui est fait dans la méthode de Vanessa :wink:

// Method: getDatabaseStructure
// Description
// * Call getTablesAndFields method
// * Call getIndex method
// * Call getRelations method
//
// Parameters
// return an C_Object that contains all database information (table, field, index, relation)
// ----------------------------------------------------
// https://blog.4d.com/detailed-analysis-database-structure/

J’ai bien regardé, tu n’as pas compris ce que je voulais dire par “approche” :

  • ces méthodes font 3 conversions xml -> objet spécifiques de la partie de “structure” analysée ; autrement dit, la conversion en objet est étroitement imbriquée dans la lecture de ce xml particulier, de ses éléments, de ses attributs…
  • j’ai utilisé une méthode de conversion xml -> objet http://forums.4d.com/Post/FR/18847378/1/18847379#18847379générique> ; le code spécifique (tables, champs, relations, index) ne travaille plus que sur l’objet résultant.

Je ne dis pas que c’est mieux ou moins bien (éternel débat sur le générique), il se trouvait juste que, disposant d’une générique qui marchait dans ce cas, ça me faisait moins de boulot.