[MS SQL Server] Unique ID auf 2 Textspalten

  • Allgemein

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von petaod.

    [MS SQL Server] Unique ID auf 2 Textspalten

    Nicht wirklich ein VB-Problem, sondern bisher noch ein reines SQL-Problem

    Ich möchte im SQL-Server eine Tabelle anlegen, die eine Unique-ID über zwei Text-Spalten legt.
    Erster Versuch:

    SQL-Abfrage

    1. CREATE TABLE TEST (
    2. txtID1 text,
    3. txtID2 text
    4. UNIQUE (txtID1, txtID2)
    5. )
    ERROR (line 4): Column 'txtID1' in table 'TEST' is of a type that is invalid for use as a key column in an index

    Ok, Text darf nicht als Key verwendet werden.
    Die eingefügten Texte sind eh numerisch, also legen wir Spalten an, die sich beim Befüllen automatisch mit dem Integer-Wert der Text-Felder füllen.

    SQL-Abfrage

    1. CREATE TABLE TEST (
    2. ID1 int DEFAULT CAST (txtID1),
    3. ID2 int DEFAULT CAST (txtID2),
    4. txtID1 text,
    5. txtID2 text
    6. UNIQUE (ID1, ID2)
    7. )
    ERROR (line 2): The name "txtID1" is not permitted in this context...Column names are not permitted.

    Damit stellt sich meine Frage:
    Wie lege ich Integer-Spalten an, dies sich beim Insert in die Textspalten automatisch befüllen?

    _
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    klicks dir sowas doch im Designer zurecht.
    Entweder im VisualStudio oder im SqlServer-mANagement-Dingsbums.

    Beim Zurechtklicksen wird auch eine StoredProc angelegt, mit dem korrekten Sql-Code.

    Must allerdings ziemlich herumsuchen - die Sql-Server-Designer sind der grottigste Grotten-Ranz, den man sich vorstellen kann.
    Das mit dem Zurechtklicken im Designer war auch mein erster Ansatz. Und ich muss EdR recht geben:
    die Sql-Server-Designer sind der grottigste Grotten-Ranz, den man sich vorstellen kann.

    Ich hab mal picoflops Links durchgearbeitet und habe dann nach einigen Hürden folgende funktionierende Variante hingekriegt:

    SQL-Abfrage

    1. CREATE TABLE TEST (
    2. ID1 AS CAST (CAST(txtID1 AS NVARCHAR) AS int) PERSISTED NOT NULL,
    3. ID2 AS CAST (CAST(txtID2 AS NVARCHAR) AS int) PERSISTED NOT NULL,
    4. txtID1 text NOT NULL,
    5. txtID2 text NOT NULL
    6. UNIQUE (ID1, ID2)
    7. )

    Interessant ist auch noch, was das SQL Server Management Studio aus der Tabelle macht, wenn ich ein CREATE-Script erzeugen lasse:

    SQL-Abfrage

    1. CREATE TABLE [dbo].[TEST](
    2. [ID1] AS (CONVERT([int],CONVERT([nvarchar],[txtID1]))) PERSISTED NOT NULL,
    3. [ID2] AS (CONVERT([int],CONVERT([nvarchar],[txtID2]))) PERSISTED NOT NULL,
    4. [txtID1] [text] NOT NULL,
    5. [txtID2] [text] NOT NULL,
    6. UNIQUE NONCLUSTERED
    7. (
    8. [ID1] ASC,
    9. [ID2] ASC
    10. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    11. ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    hmm - und das ist die Definition für einen aus 2 Text-Spalten zusammengesetzten Primärschlüssel??

    glaubichjanicht.

    Immerhin ist mir gelungen, im VS einen solchen zusammengesetzten PrimKey zu creiern:


    Aber im VS finde ich das zugehörige Sql nicht.

    Also habe ich auch in meim SqlManagerMurx eine Tabelle1 angelegt, in einem Datenbank-Diagramm - das finde ich noch am erträglichsten:


    Und da kann ich, wenn das Diagramm gespeichert, und die Änderungen übernommen sind, mir das TabellenScript als Abfrage generieren lassen:

    SQL-Abfrage

    1. USE [NORTHWND.MDF]
    2. GO
    3. /****** Object: Table [dbo].[Tabelle1] Script Date: 09/19/2012 19:24:07 ******/
    4. IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tabelle1]') AND type in (N'U'))
    5. DROP TABLE [dbo].[Tabelle1]
    6. GO
    7. USE [NORTHWND.MDF]
    8. GO
    9. /****** Object: Table [dbo].[Tabelle1] Script Date: 09/19/2012 19:24:07 ******/
    10. SET ANSI_NULLS ON
    11. GO
    12. SET QUOTED_IDENTIFIER ON
    13. GO
    14. CREATE TABLE [dbo].[Tabelle1](
    15. [ID1] [nchar](10) NOT NULL,
    16. [ID2] [nchar](10) NOT NULL,
    17. CONSTRAINT [PK_Tabelle1] PRIMARY KEY CLUSTERED
    18. (
    19. [ID1] ASC,
    20. [ID2] ASC
    21. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    22. ) ON [PRIMARY]
    23. GO

    (So, und jetzt den ganzen Quatsch wieder von meim SqlServer runter-löschen)
    Im Gegensatz zu deinen Versuchen mit "nchar" hatte ich noch eine zusätzliche Hürde:
    Mein Datentyp war text.
    Und darauf lässt sich so ziemlich nichts mit Keys machen.

    Die Idee mit nur einem CAST auf nchar oder nvarchar hatte ich zwischendrin auch mal, aber die verwarf ich wieder, weil ich mir sagte, wenn ich schon eine zusätzliche Spalte für meine Keys anlegen muss, mach ich sie gleich Integer, dann ist die Constraint-Prüfung wenigstens performant.

    Unabhängig davon klär ich mal mit demjenigen, der das "text" verbrochen hat, ob das Sinn macht oder ob ich da mal am Tabellen-Design drehen darf.
    Aber so wie ich den Laden kenne, traut sich an bestehende Spalten niemand ran, weil keiner genau weiß, welche Programme sich an die DB im Lesemodus connecten.
    Mal sehen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --