Entwickler-Ecke
Datenbanken - Indize abfragen in Tabelle und setzen per SQL
moloch - Di 12.05.09 16:06
Titel: Indize abfragen in Tabelle und setzen per SQL
Hallo Leute,
ich möchte einen Indize abfragen in einer Tabelle und wenn er nicht gesetzt ist setzen per SQL. setzen habe ich bisher so gemacht:
SQL-Anweisung
1:
| CREATE UNIQUE INDEX prima ON Tabelle (Spalte1) |
aber wie frage ich einen Indize ab damit ich nicht immer anlege beim Start des Programms?
Moderiert von
Christian S.: Delphi- durch SQL-Tags ersetzt
zuma - Di 12.05.09 16:19
müsste eigentliche eine DB-system-interne Tabelle geben, in der die Indexe stehen.
wie die bei deinem DB-System heisst -> siehe dein DB-Handbuch
die brauchste dann ja nur abfragen, ob's den Index gibt.
bei Interbase ist das irgend so ne RDB$... Tabelle, weiss den Namen nicht aus dem Kopf und hab auch gerade kein Handbuch da ;)
moloch - Mo 18.05.09 10:02
also ich habe mich entschlossen die Indizes zu löschen und dann anzulegen.
mit dieser sql funktioniert es:
SQL-Anweisung
1:
| ALTER TABLE statusp DROP CONSTRAINT PK__STATUSP__6442E2C9 |
das problem besteht jedoch daran den Schlüsselnamen auszulesen. In diesem Fall "PK__STATUSP__6442E2C9"
wie mache ich das?
beste grüße
Moderiert von
Christian S.: Delphi- durch SQL-Tags ersetzt
BenBE - Mo 18.05.09 10:32
IIRC mit SHOW INDEX FROM tabelle;
moloch - Mo 18.05.09 11:46
IIRC?? kenne ich nicht.
mach doch bitte mal eine beispiel sql
BenBE - Mo 18.05.09 11:49
IIRC = If I Remember Correctly; und dein Beispiel steht nach dem "mit" ;-)
@Ramon: Oracle nutzt doch keiner ;-)
Ramon - Mo 18.05.09 12:03
moloch hat folgendes geschrieben : |
das problem besteht jedoch daran den Schlüsselnamen auszulesen. In diesem Fall "PK__STATUSP__6442E2C9"
wie mache ich das?
|
Hängt immer vom DBMS ab? Welche Datenbank nutzt du?
Oracle könntest du z.B. so: Select * from USER_INDEXES
moloch - Mo 18.05.09 12:15
mssql
@benb ja das habe ich probiert. bei mssql funktioniert es nicht
Ramon - Mo 18.05.09 12:27
BenBE hat folgendes geschrieben : |
@Ramon: Oracle nutzt doch keiner ;-) |
Ich schon :-P
Versuch mal das:
SQL-Anweisung
1: 2: 3: 4: 5: 6:
| SELECT O.NAME TABLE_NAME,s.name AS INDEX_NAME FROM SYSOBJECTS O, SYSINDEXES S where O.TYPE = 'U' and S.ID=O.ID ORDER BY O.NAME |
moloch - Mo 18.05.09 13:16
hab was besseres gefunden
EXEC sp_helpindex "tabelle"
funktioniert super bei mssql zumindest
moloch - Mi 20.05.09 10:28
Hallo,
also in MSSQL klappt jetzt alles super. Jetzt brauche ich nur noch für Oracel
den richtigen SQL- Befehl um die Indizes der jeweiligen Tabelle rauszufinden.
löschen habe ich schon gefunden:
SQL-Anweisung
1: 2: 3:
| drop index Indexname //oder ALTER TABLE Tabellenname DROP CONSTRAINT Constraintname |
zuma - Mi 20.05.09 10:47
ich glaube, du hast da einen Verständnisfehler:
Constraints sind was anderes als Indexe !!!
constraint = Definition von Integritätsbedingungen
Eine Constraint, die einen Primary Key definiert, erzeugt in der Regel auch automatisch einen Index, d.h. aber NICHT, das du nur den Index löscht, wenn du den Constraint löscht, sondern auch den Primary Key !!!!
ist also die richtige Lösung, um NUR den Index zu entfernen.
Ramon - Mi 20.05.09 10:51
moloch hat folgendes geschrieben : |
Hallo,
also in MSSQL klappt jetzt alles super. Jetzt brauche ich nur noch für Oracel
den richtigen SQL- Befehl um die Indizes der jeweiligen Tabelle rauszufinden. |
Hatte ich oben bereits geschrieben:
SQL-Anweisung
1:
| Select * from USER_INDEXES where TABLE_NAME = 'blup' |
moloch - Mi 20.05.09 11:08
@zuma
Zitat: |
ich glaube, du hast da einen Verständnisfehler:
|
ja das glaube ich auch. Für mich war immer ein Index auf einer Tabelle = PrimärIndex.
Also das was in der jeweiligen Spalte steht z.b. 1 darf nur einmal in der Tabelle stehen.
Da wäre es evtl erstmal hilfreich in deinen Worten vielleicht zu erfahren wo der unterschied liegt.
@Ramon
danke noch mal
Ramon - Mi 20.05.09 11:12
Zitat: |
Da wäre es evtl erstmal hilfreich in deinen Worten vielleicht zu erfahren wo der unterschied liegt. |
Der Primary Key macht einen Datensatz eindeutig. Es wird in der Regel auch ein entsprechender Index über die Schlüsselfelder angelegt, da man davon ausgeht, dass in der Regel nach diesen selektiert/gesucht wird.
Zusätzliche Indizes über andere Spalten dienen der schnellere Selektion wenn diese Spalten durchsucht werden.
Zitat: |
@Ramon
danke noch mal |
Bitte
moloch - Mi 20.05.09 11:26
ja ok verstehe. der grund warum ich auf constraint überhaupt komme ist, das ich bei mssql versucht hatte den Primärindex mit
drop index tabellenname.indexname zu löschen. das ging nicht.
mit ALTER TABLE statusp DROP CONSTRAINT constraintname aber schon. im grunde gehts mir auch nur um Primärindizes jedoch war so der weg..
im grunde suche ich "nur" nach den richtigen sql's für
MSSQl, MySQL und Oracle
die die PrimärIndizes löschen damit ich sie danach wieder richtig anlegen kann. Sprich ein update möchte ich machen für die Indizes der jeweiligen Tabelle..
zuma - Mi 20.05.09 11:28
[quote="]
moloch
ja das glaube ich auch. Für mich war immer ein Index auf einer Tabelle = PrimärIndex.
Also das was in der jeweiligen Spalte steht z.b. 1 darf nur einmal in der Tabelle stehen.
Da wäre es evtl erstmal hilfreich in deinen Worten vielleicht zu erfahren wo der unterschied liegt.
[/quote]
Ein Primary Key ist KEIN Index, sondern, wie Ramon schon sagte, eine Festlegung, das eine Spalte (oder auch mehrere) eindeutig ist. Verwirrt wird dich wohl haben, das eben in der Regel automatisch bei Angabe eines Primary Key auch ein Index angelegt wird.
Dies ist aber nur 'Komfort' eines DB-Systems. Der Primary Key würde auch ohne Index eine Eindeutigkeit festlegen. Eindeutigkeit und Indexierung haben aber nichts miteinander zu tun. Die Indexierung dient nur der Performance, um eben schneller auf Datensätze zugreifen zu können.
Wenn du z.b eine Tabelle hast, in der mehrere Spalten stehen, auf der ersten einen Primary Key hast, aber oft nach der 3ten Spalte suchst, würde sich ein Index auf die 3te Spalte lohnen, da so der Zugriff darauf schneller erfolgen kann.
moloch - Mi 20.05.09 11:40
ok verstehe. warum macht man dann nicht auf jede spalte einen index?
Ramon - Mi 20.05.09 11:44
moloch hat folgendes geschrieben : |
ok verstehe. warum macht man dann nicht auf jede spalte einen index? |
Naja, du darfst nicht vergessen, dass das immer Speicher weg nimmt. Irgendwo muss der Index ja abgelegt werden.
Außerdem muss das DBMS bei der Selektion entscheiden, welchen Index es am besten benutzt. Hast du zuviele, kann es passieren, dass es vielleicht einen anderen wählt, als du erwartest.
moloch - Mi 20.05.09 11:44
... und zurück zur eigentlich frage wäre es noch wichtig für mich zu wissen wie die sql befehle lauten für MSSQL, MySQL und ORACLE den Primary Key zu löschen und anzulegen.
moloch - Mi 20.05.09 11:47
Zitat: |
Naja, du darfst nicht vergessen, dass das immer Speicher weg nimmt. Irgendwo muss der Index ja abgelegt werden.
Außerdem muss das DBMS bei der Selektion entscheiden, welchen Index es am besten benutzt. Hast du zuviele, kann es passieren, dass es vielleicht einen anderen wählt, als du erwartest. |
ah ok. ja macht sinn.
Ramon - Mi 20.05.09 11:50
moloch hat folgendes geschrieben : |
... und zurück zur eigentlich frage wäre es noch wichtig für mich zu wissen wie die sql befehle lauten für MSSQL, MySQL und ORACLE den Primary Key zu löschen und anzulegen. |
Oracle:
SQL-Anweisung
1:
| CREATE INDEX INDEXNAME ON TABELLENNAME (SPALTE1,SPALTE2,...) TABLESPACE TABLESPACENAME; |
Tablespace ist optional.
Im laufenden betrieb empfiehlt sich die Statistiken neu analysieren zu lassen:
SQL-Anweisung
1:
| analyze table TABELLENNAME compute statistics; |
Löschen:
moloch - Mi 20.05.09 13:20
löscht den jeweiligen Primärindex?
Ramon - Mi 20.05.09 13:28
moloch hat folgendes geschrieben : |
löscht den jeweiligen Primärindex? |
Ah, sorry, das oben gilt natürlich für Indizes. Muss sagen, ich werfe selten Schlüssel weg. Versuch mal sowas:
SQL-Anweisung
1:
| ALTER TABLE tabellenname DROP PRIMARY KEY; |
Anlegen kannst du ihn wieder mit:
SQL-Anweisung
1:
| ALTER TABLE tabellenname ADD (PRIMARY KEY (Spalte1, Spalte2...)); |
Das Anlegen klappt natürlich nur, wenn der Schlüssel nicht verletzt wird, also nicht doppelt vorhanden ist.
moloch - Mi 20.05.09 13:37
wegschmeissen tue ich den primärindex auch nur weil ich ihn im grunde updaten will. also erst löschen alle dann wieder richtig anlegen mit z.b. einem primärindex auf irgendeiner spalte mehr.
für mssql funktionieren die sqls schon mal nicht die du geschrieben hast. für mysql ja.
moloch - Mi 20.05.09 13:43
ist indize = index
oder ist indize ein anderes wort für primärindex?
BenBE - Mi 20.05.09 14:12
Ganz einfach:
Index = Singular
Indize = Plural
Und bzgl. dem Anlegen: Der PK gehört auf nen AutoIncrement-Spalte, und ansonsten gehören auf eindeutige Spalten (oder Spaltensammlungen) ein UNIQUE-Constraint (+Index). Ansonsten auf alles nen Index, wonach häufig gefiltert wird.
moloch - Mi 20.05.09 14:22
bei oracle kriege ich bei dieser SQL
SQL-Anweisung
1:
| ALTER TABLE StatusP ADD (PRIMARY KEY (Datum)); |
diese Meldung
Zitat: |
ORA-01449: Spalte enthält NULL-Werte; Änderung auf NOT NULL nicht möglich
|
BenBE - Mi 20.05.09 14:30
Und was ist das Problem beim Lesen UND Verstehen der Fehlermeldung?
moloch - Mi 20.05.09 14:43
ich möchte mit einer evtl auch 2 sqls einen primärindex dazufügen zu einer tabelle..
hier kriege ich beschrieben das ich eine einstellung machen müsste.. also wieder manuell.. kann ich das evtl auch mit einer sql lösen das problem?
BenBE - Mi 20.05.09 14:55
Da liest Du die Meldung falsch: Da steht nämlich einfach nur, dass er das nicht ausführen kann, da derzeit NULL-Werte in der Tabele enthalten sind und dies gegen die von dem durch den PK bedingten Constraint nicht toleriert werden.
Lösung: Vor dem Hinzufügen des PKs dafür sorgen, dass es in der Spalte des PKs keine NULL-Werte mehr gibt (UND alle Werte eindeutig sind).
moloch - Mi 20.05.09 14:58
ja das verstehe ich. die situation ist aber die folgende. es ist ein spalte zur tabelle hinzugekommen.. und genau diese spalte soll halt auch einen primär key bekommen. klar das da null drin ist oder? wenn ich die neu angelegt habe.. oder gibt es eine andere möglichkeit
Nersgatt - Mi 20.05.09 15:25
Dann musst Du die Spalte mit einem Standardwert belegen, da ja NULL nicht erlaubt ist.
1. Spalte hinzufügen (Null erlaubt)
2. Spalte mit Standardwerten füllen
3. Spalte ändern (auf NULL nicht erlaubt)
4. Spalten in den Primary Key aufnehmen
moloch - Mi 20.05.09 15:31
kann man nicht die einstellung vornehmen null erlaubt und dann den primary anlegen.. das würde ich für sinnvoll halten.. geht das nicht?
zuma - Mi 20.05.09 15:43
nein, kann nicht gehen, da ein Primary Key niemals null sein kann, er wäre dann nicht mehr eindeutig.
Ich frage mich die ganze zeit, warum du überhaupt so merkwürdige sachen wie Key's löschen und indexe neu erstellen machen willst ... Scheint mir, als ob da das Konzept generell überarbeitungswürdig ist ...
moloch - Mi 20.05.09 15:45
@zuma
ich habe schon oft geschrieben warum..
es ist im grunde ein update auf die jeweilige tabelle. es ist einfach eine spalte dazu gekommen und die soll auch einen prima haben. update sql klappt nicht oder ist noch nicht komplett beschrieben worden hier. also war der einfall erstdie primas löschen dann alle anlegen zusammen...
Ramon - Mi 20.05.09 15:59
Soll die neue Spalte mit in den Primary Key aufgenommen werden? Also ein Schlüssel aus mehreren Spalten? Das sollte kein Problem sein.
Oder soll Datum der Schlüssel werden?
In dem Fall mußt du die Spalte Datum erst mit eindeutigen Inhalt füllen.
zuma - Mi 20.05.09 16:01
nee, is nich einfach nur nen Update ...
Primary key = primärer Schlüssel <- davon kanns nur einen geben, sagt ja schon der Name ;)
die neue Spalte soll also ENTWEDER mit in den PK aufgenommen werden ODER unique (eindeutig) sein
also, entweder primärer key oder alternativer key, aber nie 2 primäre key's
so legste z.b. einen 2ten key an:
alter table tabellenname add constraint tabellenname_AKEY unique (spalte); (akey = abk. für alternate key)
moloch - Mi 20.05.09 16:15
also der key soll dazu kommen
Ramon - Mi 20.05.09 16:51
moloch hat folgendes geschrieben : |
also der key soll dazu kommen |
Also dann reicht
SQL-Anweisung
1:
| ALTER TABLE StatusP ADD (PRIMARY KEY (Datum)); |
nicht.
Du musst alle Primary Key Spalten mitnehmen:
SQL-Anweisung
1:
| ALTER TABLE StatusP ADD (PRIMARY KEY (AlterKeySpalte1,AlterKeySpalte2,Datum)); |
zuma - Mi 20.05.09 16:53
ok, wenn du deinen PK erweitern willst:
angenommen:
Alter key Nr,
neue spalte Datum
neuer Key (nr, Datum)
dann
1.) alten key droppen
drop constraint PK ...
2.) neue Spalte mit not null anlegen
alter table add ... not null;
3.) neue Spalte mit eindeutigen Daten füllen
update table set datum = einDatum
4.) neuen Key anlegen
alter table tablename add constraint table_Pk Primary key(nr, Datum);
müsste so klappen, ich mach nu erstmal feierabend, bin erst Freitag wieder online, also
happy Vatertag ;)
moloch - Mo 25.05.09 08:39
hey entschuldigt war schon weg hoffe der vatertag wurde gut überstanden.
also ich versuche eure vorschläge gleich mal..
bis später
moloch - Mo 25.05.09 15:39
hallo,
also für oracle muss ich in der tat die variante von zuma verwenden. also der part der mir noch gefehlt hatte war der default wert für die neue spalte. darf bei oracle nicht null sein, sonst gibt es fehlermeldung beim versuch die primären anzulegen.
also dank euch alle für die hilfe.
beste grüße
zuma - Mo 25.05.09 16:18
Ich denke mal, meine Variante ist für alle DB-Systeme gültig, mir ist jedenfalls noch keines untergekommen, das sich da anders verhält.
Es würde mich wundern, wenn es ein DB-System gibt, das einen Primärschlüssel mit Null-Werten (nicht 0-Werten!) zulässt.
moloch - Di 26.05.09 08:11
also bei mssql und mysql habe ich den primary gelöscht und einfach wieder mit dem ergänzenden primärindex angelegt.
bei mssql lege ich so an:
SQL-Anweisung
1:
| CREATE UNIQUE INDEX prima ON Tabelle (spalte1, spalte2, spalte3) |
bei oracle und mysql so:
SQL-Anweisung
1:
| ALTER TABLE Tabelle ADD (PRIMARY KEY (spalte1, spalte2, spalte3)) |
ist da evtl noch der hund begraben?
zuma - Di 26.05.09 10:31
also, beim ersten Beispiel hast du einen Index angelegt, beim 2ten Beispiel hast du einen Primary Key angelegt. Das ist, wie bereits oben erklärt, NICHT das gleiche!
moloch - Di 26.05.09 10:37
den index den ich bei mssql angelegt habe ich aber unique und damit passiert doch das was auch bei einem primary passiert oder? also wenn ich versuche einen 2. satz anzulegen mit den gleichen inhalten auf den jeweiligen spalten (mssql -db) dann verweigert er den satz einzutragen. wie bei einem primärkey. wo liegt dann der grundlegende unterschied. ich dachte genau das soll ein primärkey machen. doppelte einträge verhindern
zuma - Di 26.05.09 10:52
Das ist schon sehr ähnlich.
Ein Index ist aber 'nur' ein Performancebeschleuniger beim Suchen.
Die Angabe Unique ist für die DB das Kennzeichen, bei einer Spalte auf Eindeutigkeit 'aufzupassen'. Deine Zeile enthält also 2 Befehle für die DB.
Ein Primary Key macht sozusagen beides in einem Befehl, d.h. es wird eine Eindeutigkeit erzwungen und gleichzeitig ein Index auf die Spalte(n) gelegt.
Ich hoffe, das das so verständlich ist, ist schwer, das mit einfachen Worten und trotzdem korrekt zu erklären.
moloch - Di 26.05.09 10:59
hm ja ok. und wo ist das argument den primary zu nutzen wenn ich mit meiner sql das ergebnis erziele was ich auch haben wollte? also einen satz mit den selben auf den jeweiligen spalten- inhalten zu verhindern
oder kann ich es auch so machen?
zuma - Di 26.05.09 12:30
boah, wie soll ich dir das erklären ....
ich versuchs mal so:
den Primary key nutzt man in der Regel, um festzulegen, über welche(n) Wert(e) man auf einen Datensatz eindeutig zugreift. Unique Nutzt man, wenn man eine 2te Möglichkeit eines eindeutigen Zugriff's nutzen möchte.
z.B.
die Felder
Kd, Nr
bestimmen einen eindeutigen Datensatz in einer Tabelle, grundsätzlich wird auch über die beiden Felder abgefragt. (Also, Primary Key(KD, Nr) angelegt). Zusätzlich gibt es in der Tabelle ein Feld
LaufendeNr
das man z.b von einem DB-Generator belegen lässt. Dieses wird mit Unique angelegt und z.b zum verknüpfen der Tabelle mit abhängigen Tabellen genutzt.
Tabelle2 hat ein Feld ID (welches dort der PK ist), das referenziert auf Tabelle 1 Feld LaufendeNr. So kann man dann mit Hilfe von Foreign Key's die Integrität der Datenbankabhängigkeiten vom DB-System steuern lassen.
Ist sicher nicht vollkommen korrekt erklärt, aber besser weiss ich es dir im Moment nicht zu erklären.
Generell würde ich dir empfehlen, dich mal mehr mit dem Thema Datenbanken zu beschäftigen, ich kann sie zwar einigermaßen benutzen, aber zu 'Lehrerqualitäten' reichts wohl nicht so ganz ...
Nersgatt - Di 26.05.09 12:39
Ich versuch mich auch mal an einer Erklärung :D
Wir haben oft den Fall, dass ein Kunde einen Datensatz mit einer Nummer identifizieren möchte. Z.B. um bei der Dateneingabe über die Nummer auf den Datensatz zugreifen zu können. Viele User lernen diese Nummern erstaunlich schnell auswendig, wenn sie sie öfters benötigen.
Diese Nummer möchte der Kunde aber später nochmal ändern können. Wenn er z.B. Datensäte in Nummernkreisen umorganisieren möchte, oder Ähnliches.
Nehmen wir eine Tabelle mit Kunden:
Spalten: ID, NR, NAME
Ich mache einen Primärindex auf das Feld ID. Damit identifiziere ich innerhalb meiner Anwendung den Datensatz. Die ID wird einmal beim Anlegen des Datensatzes vergeben und nie mehr geändert. Außerdem bekommt der User die ID niemals zu sehen. Und ich mache einen Unique-Index auf die Spalte NR. Damit kann der Kunde eine Kundennummer nur einmal vergeben. Er kann die NR nach Lust und Laune ändern (mit der Einschränkung, dass die NR eindeutig bleibt), ohne dass ich in anderen Tabelle außer der Kundentabelle etwas ändern müsste.
moloch - Di 26.05.09 12:59
dank euch,
ich denke jetzt hab ichs begriffen. werde auch noch mal versuchen was verständliches dazu zu finden.
danke auf jeden fall für die geduldige hilfe
mkinzler - Di 26.05.09 13:05
Zudem beschleunigen Indizes zwar die Selektionen, verlangsamen aber DML-Abfragen ( Insert, Update, Delete). Da die Änderungen in den jeweiligen Indizes mit angepasst werden müssen.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!