Benutzer mit den meisten Antworten
"Default-Wert" für Spalte mit Hilfe einer Variablen setzen

Frage
-
Hallo an die Community,
der erste Beitrag ist immer der schwierigste, also geht nicht zu hart mit mir ins Gericht.
Momentan habe ich folgende Anforderung auf dem Tisch liegen:
Ein Endnutzer möchte aus einem ERP-System ein Vorgabewert auf ein Memotextfeld setzen
Im ersten Schritt habe ich mir dazu gedacht, das der Kunde über eine parametrisierte Abfrage aus dem Programm den Text eingeben kann, der wiederrum an eine Variable übergeben wird und der Inhalt den Vorgabewert einer bestimmten Spalte setzt.Declare @Aktionstext nvarchar(max) -- CONSTRAINT entfernen ALTER TABLE dbo.BELEG_Extra Drop CONSTRAINT col_extra_AKTION_def -- CONSTRAINT hinzufügen ALTER TABLE dbo.BELEG_Extra ADD CONSTRAINT col_extra_AKTION_def DEFAULT @Aktionstext FOR _AKTION ; GO
Versucht man das oben genannte Skript auszuführen bekommt man die Meldung das Variablen nicht erlaubt(?) sind?
Meldung 112, Ebene 15, Status 4, Zeile 9 Variablen sind in der ALTER TABLE-Anweisung nicht zulässig.
Hat irgendwer eine alternative Idee? Paralell werde ich das ganze einmal mit Programminternen Mitteln prüfen.
Vielen Dank vorab,
M.Heitmann
Antworten
-
Hallo Michael,
Stefan hat die entscheidenden Hinweise bereits gegeben. Einen wichtigen Punkt in Bezug auf die Security sowie einen möglichen Lösungsansatz möchte ich gerne noch hinzufügen:
Security
EXEC sp_executeSQL ist die einzige Möglichkeit, wenn man Deinem Lösungsansatz folgen möchte. Jedoch gilt es zu bedenken, dass für eine solche Aktion ALTER-Berechtigugen auf dem Objekt erforderlich sind. Würdest Du diese Möglichkeit in Betracht ziehen, können die User nicht nur DEFAULTS ändern sondern die komlette Relation ändern / löschen / Inhalte mit TRUNCATE löschen, ...
Ich würde diesen Ansatz - obwohl gem. Deiner Vorgehensweise einzig möglich - nicht verfolgen.
Ich würde stattdessen eine Lösung mit einer Funktion avisieren - hier gibt es keine Probleme
Zunächst wird die Relation für die Speicherung der Konfiguration erstellt
-- Erstellen einer Konfigurationsrelation CREATE TABLE dbo.configuration ( config_flag varchar(20) NOT NULL, config_value varchar(max) NOT NULL, CONSTRAINT pk_configuration PRIMARY KEY CLUSTERED (config_flag) ); GO INSERT INTO dbo.configuration (config_flag, config_value) VALUES ('default_foo_col1', 'Das ist nur ein Default'); GO
Nachdem die Relation erstellt wurde, kann nun die Funktion erstellt werden, die später als DEFAULT für die Relation verwendet wird.
CREATE FUNCTION dbo.fn_GetDefault(@config_flag varchar(20)) RETURNS varchar(max) AS BEGIN DECLARE @ReturnValue varchar(max) SELECT @ReturnValue = config_value FROM dbo.configuration WHERE config_flag = @config_flag RETURN @ReturnValue END GO
Nachdem alle Vorarbeiten abgeschlossen sind, kann nun die eigentliche Relation erstellt werden.
CREATE TABLE dbo.foo ( Id int not null identity (1, 1), col1 varchar(256) not null DEFAULT (dbo.fn_GetDefault('default_foo_col1')) CONSTRAINT pk_foo_id PRIMARY KEY CLUSTERED (Id) )
So, und nun zwei Datensätze eintragen; zwischen den beiden Eintragungen wird jedoch der Standardwert geändert :)
-- Erster Datensatz INSERT INTO dbo.foo DEFAULT VALUES; -- Update des Standardtextes UPDATE dbo.configuration SET config_value = 'Das ist jetzt der neue Text' WHERE config_flag = 'default_foo_col1' -- Zweiter Datensatz INSERT INTO dbo.foo DEFAULT VALUES;
Und hier das Ergebnis:
Viel Spaß beim Experimentieren :)
Ich habe nun - auf Grund der Komplexität - aus diesem Thema einen eigenen Blogeintrag gemacht. Er berücksichtigt alle PRO und CONS zu diesem Thema:
http://db-berater.blogspot.de/2013/06/dynamische-standardwerte-fur-attribute.html
Uwe Ricken
MCM SQL Server 2008
MCSE - SQL Server 2012
MCSA - SQL Server 2012
db Berater GmbH
http://www-db-berater.de
SQL Server Blog (german only)
- Bearbeitet Uwe RickenMVP Freitag, 7. Juni 2013 09:10
- Als Antwort vorgeschlagen Olaf HelperMVP Freitag, 7. Juni 2013 09:24
- Als Antwort markiert M. Heitmann Donnerstag, 13. Juni 2013 13:08
Alle Antworten
-
Hallo Michael,
einerseits ist das, was Du da machen willst, sehr gefährlich. Denn wer sagt dir, dass die User sich ihr Zeugs nicht gegenseitig überschreiben? Denn die Tabelle(n) werden ja nicht nur von diesem einen Benutzer verwendet. Zum anderen wird ein Standardwert normalerweise einmal gesetzt und dann hat sich das. Änderungen des Standardwerts, die durch Benutzer erfolgen können, würde ich nicht erlauben.
In dem Fall sollte man eher eine Standardwerttabelle für das Eingabeformular bauen. D.h. Du hast eine Tabelle mit Formularname, BenutzerId, Feldname und Standardwert. Diesen Wert kannst Du dann im Eingabeformular des Benutzers bei Neuanlage eines Datensatzes vorgeben.
Wenn Du das unbedingt so machen willst, müsstest Du das ALTER Statement dynamisch als String zusammenstellen und dann bspw. über sp_executesql( ... ) ausführen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET
http://www.asp-solutions.de/ - Consulting, Development
http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community
- Bearbeitet Stefan FalzModerator Donnerstag, 6. Juni 2013 11:15
-
Hallo Michael,
Stefan hat die entscheidenden Hinweise bereits gegeben. Einen wichtigen Punkt in Bezug auf die Security sowie einen möglichen Lösungsansatz möchte ich gerne noch hinzufügen:
Security
EXEC sp_executeSQL ist die einzige Möglichkeit, wenn man Deinem Lösungsansatz folgen möchte. Jedoch gilt es zu bedenken, dass für eine solche Aktion ALTER-Berechtigugen auf dem Objekt erforderlich sind. Würdest Du diese Möglichkeit in Betracht ziehen, können die User nicht nur DEFAULTS ändern sondern die komlette Relation ändern / löschen / Inhalte mit TRUNCATE löschen, ...
Ich würde diesen Ansatz - obwohl gem. Deiner Vorgehensweise einzig möglich - nicht verfolgen.
Ich würde stattdessen eine Lösung mit einer Funktion avisieren - hier gibt es keine Probleme
Zunächst wird die Relation für die Speicherung der Konfiguration erstellt
-- Erstellen einer Konfigurationsrelation CREATE TABLE dbo.configuration ( config_flag varchar(20) NOT NULL, config_value varchar(max) NOT NULL, CONSTRAINT pk_configuration PRIMARY KEY CLUSTERED (config_flag) ); GO INSERT INTO dbo.configuration (config_flag, config_value) VALUES ('default_foo_col1', 'Das ist nur ein Default'); GO
Nachdem die Relation erstellt wurde, kann nun die Funktion erstellt werden, die später als DEFAULT für die Relation verwendet wird.
CREATE FUNCTION dbo.fn_GetDefault(@config_flag varchar(20)) RETURNS varchar(max) AS BEGIN DECLARE @ReturnValue varchar(max) SELECT @ReturnValue = config_value FROM dbo.configuration WHERE config_flag = @config_flag RETURN @ReturnValue END GO
Nachdem alle Vorarbeiten abgeschlossen sind, kann nun die eigentliche Relation erstellt werden.
CREATE TABLE dbo.foo ( Id int not null identity (1, 1), col1 varchar(256) not null DEFAULT (dbo.fn_GetDefault('default_foo_col1')) CONSTRAINT pk_foo_id PRIMARY KEY CLUSTERED (Id) )
So, und nun zwei Datensätze eintragen; zwischen den beiden Eintragungen wird jedoch der Standardwert geändert :)
-- Erster Datensatz INSERT INTO dbo.foo DEFAULT VALUES; -- Update des Standardtextes UPDATE dbo.configuration SET config_value = 'Das ist jetzt der neue Text' WHERE config_flag = 'default_foo_col1' -- Zweiter Datensatz INSERT INTO dbo.foo DEFAULT VALUES;
Und hier das Ergebnis:
Viel Spaß beim Experimentieren :)
Ich habe nun - auf Grund der Komplexität - aus diesem Thema einen eigenen Blogeintrag gemacht. Er berücksichtigt alle PRO und CONS zu diesem Thema:
http://db-berater.blogspot.de/2013/06/dynamische-standardwerte-fur-attribute.html
Uwe Ricken
MCM SQL Server 2008
MCSE - SQL Server 2012
MCSA - SQL Server 2012
db Berater GmbH
http://www-db-berater.de
SQL Server Blog (german only)
- Bearbeitet Uwe RickenMVP Freitag, 7. Juni 2013 09:10
- Als Antwort vorgeschlagen Olaf HelperMVP Freitag, 7. Juni 2013 09:24
- Als Antwort markiert M. Heitmann Donnerstag, 13. Juni 2013 13:08
-
Hallo Uwe,
vielen Dank für diese ausführliche Beschreibung.
Aus pers. Interesse habe ich diesen Lösungsweg ausprobiert aber nicht implementiert.
Habe auf Möglichkeiten des ERP-Systems zurückgegriffen.
Dort gibt es sogenannte globale Freie Felder die zur freien Verwendung bereits vom Hersteller implementiert wurden.
Diese können nur von einem Benutzer geändert werden.
Vielen Dank für die kompetente und schnelle Hilfe.
M.Heimtann