Bonjour,
je suis contraint de "développer" ma propre version de DDLgen pour Sybase 10.X.
je n'arrive pas à déterminer à quel segment appartient une table.
qui aurait la réponse ?
merci par avance.
Bonjour,
je suis contraint de "développer" ma propre version de DDLgen pour Sybase 10.X.
je n'arrive pas à déterminer à quel segment appartient une table.
qui aurait la réponse ?
merci par avance.
Sybase 10??? Ouch!
Ceci étant, cette information existe dans sysindexes.segment, à joindre avec syssegments.
Ensuite, on peut voir sur quel fragment est mappé le segment (dans master..sysusages), et de là sur quel device.
Tu n'as peut-être pas perl/sybperl installé, mais je te suggère d'étudier dbschema.pl (www.midsomer.org) qui implémente déjà à peu près tout ce que fait ddlgen.
Michael
La table syssegments n'ayant pas subi d'évolution depuis la version 10 (qui date quand même de 1994), le code suivant devrait marcher :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 select name_object = i.name, i.indid, segment_num = s.segment, segment_name = s.name from syssegments s, sysindexes i where s.segment = i.segment order by i.name /* indid donne une indication sur la nature de l'objet */
Merci pour vos réponses...
j'avais déjà la requête qui détermine à quel segment appartient un indexe. (si c'est bien ce que fait la requête que m'a donnée dbafranck). D'ailleurs, j'ai vérifié, et elle ne marche pas pour une des tables que j'ai.
même remarque pour Michael Peppler.
ou alors j'ai loupé quelque chose ?
Michael, j'ai déjà vu tes messages sur sybperl sur un autre sujet. Je ne sais pas si je peux installer ça si facilement sur nos machines ici ! Je sais que je peux utiliser le C sans problèmes. Mon ddlgen ne marche pas trop mal si on exclut cette histoire de segment. Pour l'instant, je triche, j'utilise la requête suivante:
(%s à remplacer par le nom de table). c'est moyen, mais ça marche dans le cas particulier de nos bases qui n'ont pas d'autre segments.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 SELECT CASE type WHEN 'L' THEN 'logsegment' WHEN 'S' THEN 'system' ELSE 'default' END from sysobjects where id = object_id('%s')
Pour sybperl tu peux probablement l'installer assez facilement dans ton "home" directory (sous unix) sans avoir besoin des droits administrateur.
Maintenant il serait quand même intéressant de voir le contenu de sysobjects et de sysindexes pour la table qui pose problème...
Michael
Pour la table 'utilisateur'
La requête
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 1> select * from sysobjects where name = 'utilisateur' 2> go name id uid type userstat sysstat indexdel schemacnt sysstat2 crdate expdate deltrig instrig updtrig seltrig ckfirst cache audflags objspare versionts loginame ------------------------------ ----------- ------ ---- -------- ------- -------- --------- ----------- -------------------------- -------------------------- ----------- ----------- ----------- ----------- ----------- ------ ----------- ----------- -------------------------- ------------------------------ utilisateur 1601440779 1 U 0 -32685 2 246 0 Dec 24 1999 3:54AM Dec 24 1999 3:54AM 0 0 0 0 0 0 0 0 0x0005ce6004e7db1e00010000 NULL (1 row affected)
ne retourne rien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part 1> select * from sysindexes where name = 'utilisateur'
le requête
retourne qq chose, mais l'index qui appartient à cette table n'a pas forcément le même nom que la table (cas particulier dans lequel la requête de dbafranck marche).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 1> select * from sysindexes where id = object_id('utilisateur') 2> go name id indid doampg ioampg oampgtrips status2 ipgtrips first root distribution usagecnt segment status maxrowsperpage minlen maxlen maxirow keycnt keys1 keys2 soid csid base_partition fill_factor res_page_gap exp_rowsize keys3 identitygap ------------------------------ ----------- ------ ----------- ----------- ----------- ------- ----------- ----------- ----------- ------------ -------- ------- ------ -------------- ------ ------ ------- ------ -------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------- -------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------- ---- ---- -------------- ----------- ------------ ----------- -------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------- ----------- K_user 1601440779 1 2760 591105 0 0 0 586768 591224 0 0 1 146 0 5 604 7 1 0x81020100340200010002000000000000 NULL 0 0 1 0 0 0 NULL NULL (1 row affected)
je n'arrive plus à faire marcher scview (pourquoi ?) mais si je pouvais, je pourrais montrer que les tables pour lesquelles la requête de dbafranck marche sont celles qui ont un index de même nom que celle de la table.
voici la DDL que me génère mon programme :
Pour terminer, je mets un extrait de la doc de Sybase sur la table Sysindexes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 print 'utilisateur' SETUSER 'dbo' go IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'utilisateur') DROP TABLE utilisateur go CREATE TABLE dbo.utilisateur ( numuser smallint NOT NULL, nomuser varchar(80) NOT NULL, loginuser varchar(30) NOT NULL, nivuser tinyint NOT NULL, indutilimit char(1) NULL, nbminutej int NULL, nbminuteto int NULL, nbconnectj int NULL, indutiequ char(1) NULL, enuminspecti int NULL, codapp varchar(8) NULL, indactifuti char(1) NULL, indprodlimit char(1) NULL, indgrdcompte char(1) NULL, codsection char(8) NULL, libemail char(80) NULL, codcompagnie char(8) NULL, libmotdepass char(255) NULL, indmdpchgaut char(1) NULL, enumstatututi smallint NULL, enumprofiluti smallint NULL, datembauche datetime NULL, telephone varchar(20) NULL, fax varchar(20) NULL, codcrea int NULL, datcrea datetime NULL, codmodif int NULL, datmodif datetime NULL ) on 'default' go print 'K_user' CREATE UNIQUE CLUSTERED INDEX K_user ON dbo.utilisateur (numuser) on 'default' go GRANT SELECT on utilisateur to grp_dev go GRANT SELECT on utilisateur to role_gbprod_dev go GRANT INSERT on utilisateur to role_gbprod_dev go GRANT UPDATE on utilisateur to role_gbprod_dev go GRANT DELETE on utilisateur to role_gbprod_dev go SETUSER go
En gros, pour moi, il peut y avoir des lignes associées à des tables, mais pas pour toutes les tables.sysindexes contains one row for each clustered index, one row for each
nonclustered index, one row for each table that has no clustered index, and
one row for each table that contains text or image columns.
Voilà où j'en suis... je paie un menu big mac à qui trouve la solution
Hmmm... j'utilise la requète suivante
Si indid = 0 alors il s'agit de la table, si indid = 1 il s'agit du clustered index (en mode APL, et dans ce cas il n'y a pas d'entrée avec indid = 0), et si indid = 255 alors il s'agit des colonnes de type TEXT/IMAGE de la table.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 select "table" = object_name(i.id) , "index" = i.name , i.indid , s.segment , s.name from sysindexes i , syssegments s where i.segment = s.segment order by 1, 3
Cette requète devrait marcher en version 10 (je viens de l'essayer avec succès dans une 4.9.2 :-)
Michael
Encore merci !!... mais désolé si j'insiste. Je comprends que ta requête me renvoie toujours l'index de ma table et le segment associé à l'index :
Si tu regardes la DDL, tu vois que le CREATE TABLE se fait sur un segment (default) et le CREATE INDEX sur un segment (default). Sur mon cas, c'est le même segment, mais il se pourrait que ce soit différent, et dans ce cas, je suis sûr que ta requête ne me donnerait pas le segment de la table.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 1> SELECT "table" = object_name(i.id) 2> , "index" = i.name 3> , i.indid 4> , s.segment 5> , s.name 6> FROM sysindexes i 7> , syssegments s 8> WHERE i.segment = s.segment and i.id = object_id('utilisateur') 9> ORDER BY 1, 3 10> go table index indid segment name ------------------------------ ------------------------------ ------ ------- ------------------------------ utilisateur K_user 1 1 default (1 row affected)
J'espère que je ne me trompe pas !
Si, justement.
Il y a dans sysindexes la ligne pour la table (indid 0) et pour chaque indexe.
Par example:
On voit dans cette liste que les tables (et les indexes "clustered") sont sur le segment "logindb_data_seg"), alors que les autres indexes sont sur "logindb_idx_seg".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 table index indid segment name ------------------------------ ------------------------------ ------ ------- ------------------------------ client_connect client_connect 0 4 logindb_data_seg client_connect client_connect_pk_idx 2 4 logindb_data_seg login_failed login_failed 0 4 logindb_data_seg login_history login_history 0 4 logindb_data_seg server_connect server_connect 0 4 logindb_data_seg server_connect server_connect_pk_idx 2 3 logindb_idx_seg server_connect server_connect_uk_idx 3 4 logindb_data_seg sqr_database sqr_database 0 4 logindb_data_seg sqr_database sqr_database_pk_idx 2 3 logindb_idx_seg sqr_database sqr_database_uk_idx 3 4 logindb_data_seg
Michael
voici ce que donne ta requête chez moi (j'ai filtré):
moi je ne vois que l'index.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 utiapp K_utiapp 1 1 default utilisateur K_user 1 1 default utimultibases utimultibases 0 1 default
peut être que tes tables qui ont le indid à 0 n'ont pas de "clustered index" ? lorsque indid > 1 c'est je cite:
peux-tu générer le DDL de ces tables, qu'on vérifie ?if a nonclustered index or a clustered index on a data-only-locked table
Il est important de comprendre ce qu'est un "clustered index" pour Sybase ASE pour comprendre les données dans sysindexes.
Si tu as une table qui est en APL avec un index clustered alors le clustered index EST la table (cad les pages "feuilles" de l'indexe correspondent aux pages datas de la table) et les deux sont en fait indissociables (et il n'y a qu'une ligne dans sysindexes avec un indid = 1).
Dans le cas des tables DOL le clustered index est séparé de la table elle-même, mais la table "suit" le clustered index (cad si on crée le clustered index sur le segment toto alors la table sera copiée sur le segment toto également.) Dans ce cas il y a deux lignes dans sysindexes.
Donc - le résultat ci-dessus est tout à fait cohérent.
Michael
j'ai un peu du mal à suivre... (APL, DOL ?)
mais j'ai fait un expérience : j'ai passé le DDL suivant en entrée à isql :
je crée l'index sur un segment différent de la table. Mais lorsque j'extrais le DDL avec DB artisan, il me sort bien le segment system et non default comme je m'y attendais.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 use fcgbechant2rec go print 'utilisateur' SETUSER 'dbo' go IF EXISTS (SELECT 1 FROM sysobjects WHERE name = 'utilisateur') DROP TABLE utilisateur go CREATE TABLE dbo.utilisateur ( numuser smallint NOT NULL, nomuser varchar(80) NOT NULL, loginuser varchar(30) NOT NULL, nivuser tinyint NOT NULL, indutilimit char(1) NULL, nbminutej int NULL, nbminuteto int NULL, nbconnectj int NULL, indutiequ char(1) NULL, enuminspecti int NULL, codapp varchar(8) NULL, indactifuti char(1) NULL, indprodlimit char(1) NULL, indgrdcompte char(1) NULL, codsection char(8) NULL, libemail char(80) NULL, codcompagnie char(8) NULL, libmotdepass char(255) NULL, indmdpchgaut char(1) NULL, enumstatututi smallint NULL, enumprofiluti smallint NULL, datembauche datetime NULL, telephone varchar(20) NULL, fax varchar(20) NULL, codcrea int NULL, datcrea datetime NULL, codmodif int NULL, datmodif datetime NULL ) on 'default' go print 'K_user' CREATE UNIQUE CLUSTERED INDEX K_user ON dbo.utilisateur (numuser) on 'system' go GRANT SELECT on utilisateur to grp_dev go GRANT SELECT on utilisateur to role_gbprod_dev go GRANT INSERT on utilisateur to role_gbprod_dev go GRANT UPDATE on utilisateur to role_gbprod_dev go GRANT DELETE on utilisateur to role_gbprod_dev go SETUSER go
donc le segment qui compte semble être celui de l'index.
en tout cas merci. Lorsque j'aurais le temps j'essaierai de comprendre un peu mieux.
APL: All Pages Locking - granularité des verrous: 1 page.
DOL: Data only locking - granularité des verrous: 1 enregistrement (il y a deux variantes, sans importance pour ce qui nous interesse)
Dans ton cas, puisque tu crée un index "clustered" la table va "suivre" l'index, et se trouver sur le segment où l'index est créé.
Fait le même exercice en ne créant pas d'index "clustered", et un autre index et tu verras que le segment définis pour la table sera toujours valide.
Michael
OK un merci (beaucoup!) et je pars en week end !
Bonjour,
Je ne sais pas si Michael (Peppler) tombera sur ce message.
Je voudrais apporter quelques précisions : il *semble* que ce que tu as dit sur les indexes clustered soit vrai, c'est à dire que la table se trouve sur le même segment que l'index clustered qui lui est associé, sinon il reste sur son segment d'origine, auquel cas il y a une entrée dans sysindexes avec indid = 0. Mais c'est seulement lorsque cet index est UNIQUE CLUSTERED.
Confirmes-tu ? (ou quelqu'un d'autre ?)
L'option UNIQUE n'est pas significative. C'est uniquement l'attribut CLUSTERED qui indique si la table va "suivre" l'indexe au niveau du segment.
Michael
Partager