SQL Foreign Keys in SQL Server

powerfx

Admiral
Registriert
Apr. 2009
Beiträge
9.351
Hallo,

der SQL Server (über Visual Studio) will irgendwie nicht so wie ich.

Ich habe eine LocalDB mit ein paar Tabellen. Als Beispiel diese zwei (etwas verkürzt):
Code:
CREATE TABLE [dbo].[Card] (
    [Id]                 INT           IDENTITY (1, 1) NOT NULL,
    [CardNo]             VARCHAR (15)  NOT NULL,
    [ValidUntil]         DATE          NOT NULL,
    [RCountryID]         CHAR (2)      NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Card_Country] FOREIGN KEY ([RCountryID]) REFERENCES [dbo].[Country] ([CountryID])
);
und
Code:
CREATE TABLE [dbo].[Country] (
    [CountryID]   CHAR (2)      NOT NULL,
    [CountryName] NVARCHAR (60) NOT NULL,
    PRIMARY KEY CLUSTERED ([CountryID] ASC)
);
[Country] ist bereits gefüllt und soll auch momentan gar nicht geändert werden.
Fülle ich jetzt bei [Card] in einer Zeile alle Felder aus, die kein FK sind, kann der Datensatz problemlos gespeichert werden. Bei jedem FK (die sind vom Prinzip alle gleich), also etwa "DE" als CountryID, kommt aber Folgendes:
The data in row 1 was not committed.
Error Source: .Net SqlClient Data Provider.
Error Message: The connection is broken and recovery is not possible. The client driver attempted to recover the connection one or more times and all attempts failed.

Was stimmt denn hier mit den FKs nicht?
 
Hallo powerfx,

Auch wenn man mich jetzt 'Teeren und Federn' möchte, würde ich empfehlen die Tabellen und Einschränkungen zuerst in Microsoft Access anzulegen und, wenn diese so funktionieren wie Du es dir wünscht, angepasst nach Microsoft SQL Server zu übertragen.

Viel Erfolg
 
Hallo Powerfx,

wie trägst Du Deine Daten ein? Nutzt Du dazu den SQL ServerManager oder eine .Net Komponente in einem eigenen Programm?
Falls letzteres der Fall sein sollte, würde ich versuchen die Daten erst mal im SSM zu schreiben. Aufgrund der Fehlermeldung vermute ich nämlich eher, dass ein Problem mit einer falsch angesprochenen .Net Komponenete besteht.
 
Es passiert schon, wenn ich es in der Datenansicht der Tabelle mache, also nicht etwa über eine kompilierte Anwendung, sondern direkt in der IDE.

Access habe ich eigentlich nicht. Wenn, dann könnte ich mir zwar vielleicht eine Demo o.ä. installieren, aber erstens läuft sie ja irgendwann ab, zweitens kenne ich Access auch nicht besonders gut und drittens sind es ja hier relativ einfache Strukturen. Das muss doch auch so möglich sein.
 
Die im Eingangsposting angeführte Fehlermeldung ist nur ein Folgefehler. Bietet die IDE keine Möglichkeit, sich die Fehlermeldung komplett anzeigen zu lassen?
 
Es ist eine eingeblendete MessageBox. Die Datenbank ist danach defekt. Da lässt sich nichts mehr mit machen, weil Connection immer broken ist. Also entweder neu erstellen oder die Datei mit einer vorher gesicherten Version ersetzen.

Der Fehler selbst entsteht ja offenbar beim SQL Server und nicht in VS. Ich kann erst morgen genauer schauen, vielleicht gibt es irgendwo Logs dazu.
 
powerfx schrieb:
Die Datenbank ist danach defekt. Da lässt sich nichts mehr mit machen, weil Connection immer broken ist.
Du kannst Dich anschließend nicht mehr neu verbinden? Normalerweise dürften nach einem fehlgeschlagenen Insert bestenfalls die Tabellen gelockt sein.

powerfx schrieb:
Der Fehler selbst entsteht ja offenbar beim SQL Server und nicht in VS.
Davon ist auszugehen. Hast Du eventuell irgend ein Administrationstool zur Verfügung? Dann würde ich versuchen, damit den SQL-Befehl auszuführen. Das ergibt dann hoffentlich eine aussagekräftigere Fehlermeldung.
 
Du musst dir nicht unbedingt das SSM installieren (auch wenn es durchaus zu empfehlen wäre), es geht auch einfach im Visual Studio eine .sql Datei anzulegen und mit den entsprechenden Verbindungsdaten ausführen zu lassen. Da solltest du eine bessere Fehlermeldung erhalten.
 
Am ForeignKey liegt es denke ich definitiv nicht.
Ich habe gerade mal schnell die Tabellen von Dir angelegt und einen Datensatz eingefügt (SQL-Server 2008R2 über SSM)
Code:
CREATE TABLE [dbo].[Country] (
    [CountryID]   CHAR (2)      NOT NULL,
    [CountryName] NVARCHAR (60) NOT NULL,
    PRIMARY KEY CLUSTERED ([CountryID] ASC)
);

CREATE TABLE [dbo].[Card] (
    [Id]                 INT           IDENTITY (1, 1) NOT NULL,
    [CardNo]             VARCHAR (15)  NOT NULL,
    [ValidUntil]         DATE          NOT NULL,
    [RCountryID]         CHAR (2)      NULL,
    PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Card_Country] FOREIGN KEY ([RCountryID]) REFERENCES [dbo].[Country] ([CountryID])
);

insert into country values ('DE', 'Deutschland');
insert into country values ('FR', 'Frankreich');

insert into card (CardNo,ValidUntil,RCountryID) values ('ABC123','2018-01-01', 'DE')
insert into card (CardNo,ValidUntil,RCountryID) values ('XYZ789','2019-05-01', 'FR')

select * from Card;

Funktioniert ohne Fehler!
Ergebnis:
Code:
Id	CardNo	ValidUntil	RCountryID
1	ABC123	2018-01-01	DE
2	XYZ789	2019-05-01	FR

Auch dass die Datenbank anschließend zerschossen ist deutet darauf hin, dass etwas mit der Verbindung und der Ansprache der Datenbank nicht stimmt.
 
Hmm, ja... Danke für die Mühe.

Also ohne das Land funktioniert ja auch bei mir alles. So was hier:
Code:
insert into card (CardNo,ValidUntil) values ('ABC123','2018-01-01')
Aber sobald ich da irgendwie eine RCountryID einfüge, geht's kaputt, übrigens unabhängig davon, ob es eine valide ID ("DE") oder nicht ("ZZ") ist. Nur wenn es etwas anderes als CHAR(2) ist, kommt eine entsprechend richtige Meldung.

Sobald es kaputt ist, bleibt es kaputt. Auch nach Neustart von VS oder des ganzen Rechners (und damit auch evtl. Dienste). Bei z.B. SELECT * FROM Card heißt es dann:
Msg 0, Level 11, State 0, Line 0
The connection is broken and recovery is not possible. The client driver attempted to recover the connection one or more times and all attempts failed. Increase the value of ConnectRetryCount to increase the number of recovery attempts.

Es funktioniert erst wieder, wenn ich die DB lösche und neu anlege oder die beiden zuvor gesicherten Dateien (.mdf, .ldf) zurück ins Projektverzeichnis kopiere.
 
Zurück
Oben