SQL Server CE 3.5: Datensatz kopieren mit Parms

Liebe/-r Experte/-in,

Im Forum hat leider keiner auf meine Frage geantwortet, deshalb auf diesem Weg; ich programmiere zurzeit mit VB.net in VS2008 mit einer SQL Server CE 3.5-Datenbank.

Folgender Sachverhalt:
Ich möchte innerhalb einer Tabelle einen Datensatz kopieren, wobei 2 Feldinhalte aber nicht aus dem kopierten Datensatz, sondern aus Variablen kommen. Den Inhalt dieser Variablen habe ich in Parameter gepackt und will sie nicht als Literale in den SQL-String nehmen (Stichwort „SQL Injection“).

Mein Code sieht so aus:

Dim Cmd As SqlCeCommand = GetDbCommand()
Dim SatzID As String = "1234"
Dim NeueSatzID As String = "9876"
Dim NeueParentID As String = "2345"

Cmd.Parameters.Clear()
Cmd.Parameters.AddWithValue("SatzID", SatzID)
Cmd.Parameters.AddWithValue("NeueSatzID", NeueSatzID)
Cmd.Parameters.AddWithValue("NeueParentID", NeueParentID)
Cmd.CommandText = "INSERT INTO MeineTabelle (SatzID, Feld1, Feld2, Feld3) " & \_
"SELECT @NeueSatzID, Feld1, @NeueParentID, Feld3 " & \_
 "FROM MeineTabelle WHERE SatzID = @SatzID"
Cmd.ExecuteNonQuery()

Damit wirft er aber eine SqlCeException „Unzulässiger Parameter an diesem Ort. Stellen Sie sicher, dass das Symbol ‚@‘ sich an einem gültigen Ort befindet oder dass Parameter in dieser SQL-Anweisung gültig sind.“

Auch eine Umstellung des Befehls auf

Cmd.CommandText = "INSERT INTO MeineTabelle (SatzID, Feld2, Feld1, Feld3) " & \_
 "VALUES (@NeueSatzID, @NeueParentID, (SELECT Feld1, Feld2 " & \_
 "FROM MeineTabelle WHERE SatzID = @SatzID))"

wirft eine SqlException „Fehler beim Analysieren der Abfrage. [Token line number … Token in error = SELECT]“

Hast Du eine Idee? Das müsste doch zumindest so ähnlich funktionieren …

Vielen Dank fürs Lesen, Überlegen und Antworten!
Thomas

Hi,

in erster Version des Codes scheint das Problem in Benennung der Parameter in Cmd.Parameters.AddWithValue zu liegen - es fehlen dort die @-Zeichen:

Cmd.Parameters.AddWithValue("@SatzID", SatzID)
Cmd.Parameters.AddWithValue("@NeueSatzID", NeueSatzID)
Cmd.Parameters.AddWithValue("@NeueParentID", NeueParentID)

Diese Anpassung sollte meiner Meinung nach (testen kann ich es momentan leider nicht) zum Erfolg führen.

Das Problem mit der zweiten Variante ist nutzung von insert mit values und select - es verträgt sich nicht. entweder nutzt man

insert into x (f1, f2, …) values (v1, v2, …)

oder

insert into x (f1, f2, …) select (…)

Gruß
Erich

Hallo Thomas,

das ist ein wenig merkwürdig was du da versuchst! :smile:

Denn was du da Programmiert ist ein anstoßen einer Stored Procedure.

Also das solltest du anders anpacken!

Versuche das einmal so:

Ich kann nicht genau versprechen das es so sofort funzt, da ich momentan keine Zeit habe und nicht genauer nachschauen kann, aber das sollte Dir helfen!!!

Wenn nicht schreibe mir noch einmal:
videakulix [add] gmx [PUNKT] de

Dann schaue ich mal genauer nach!

MfG.:

Sascha D. Hlbach

'________________VB CODE
Dim SatzID As String = „1234“
Dim NeueSatzID As String = „9876“
Dim NeueParentID As String = „2345“

Dim Cmd As SqlCeCommand = GetDbCommand()
Cmd.Parameters.Clear()
Cmd.Parameters.AddWithValue("@SatzID", SatzID)
Cmd.Parameters.AddWithValue("@NeueSatzID", NeueSatzID)
Cmd.Parameters.AddWithValue("@NeueParentID", NeueParentID)
Cmd.CommandText = „MeineProcedure“
Cmd.ExecuteNonQuery()

'__________________SQL CODE
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
– =============================================
– Author:
– Create date:
– =============================================
ALTER PROCEDURE [dbo].[adresse_get]
@SatzID VARCHAR(50)
,@NeueSatzID VARCHAR(50)
,@NeueParentID VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO MeineTabelle
(
SatzID
,Feld1
,Feld2
,Feld3
)
(
SELECT
@NeueSatzID
,Feld1
,@NeueParentID
,Feld3
FROM
MeineTabelle
WHERE
SatzID = @SatzID
)
END

Hallo Sascha,

vielen Dank für Deine Antwort, aber anscheinend werden von SQL Server CE keine Stored Procedures unterstützt.
Und einfache SQL-Commands (SELECT, UPDATE, INSERT) funktionieren mit Parametern wie z.B.
SELECT * FROM MeineTabelle WHERE Feld1 = ‚M‘ AND ParentID = @ParentID
Auf diese Art und Weise, also ohne Stored Procedures, wird das auch in einigen Tutorials dargestellt.

Aber nochmals danke fürs Antworten.
Schöne Grüße
Thomas

Hallo Erich,

vielen Dank für Deine Antwort!
Das fehlende @-Zeichen bei der Definition der Parameter kann nicht das Problem sein, da das mit andern SQL-Befehlen einwandfrei funktioniert. Versucht habe ich’s natürlich trotzdem, hat aber nix gebracht.
Wenn Du sagst, dass ein Mischen von VALUES und SELECT nicht zulässig ist, glaube ich Dir das natürlich und beschränke mich auf meine erste Version. Da habe ich jetzt nochmal mit verschiedenen Klammersetzungen experimentiert, jedoch ohne Ergebnis.
Falls Du mal Muße haben solltest, wäre es wirklich nett, wenn Du das Beispiel bei Dir nachstellen könntest …
Ein anderer Experte hat geantwortet, dass ich den SQL-Befehl in eine Stored Procedure auslagern soll; das wird aber offensichtlich nicht von SQL Server CE unterstützt.

Nochmals vielen Dank und schöne Grüße
Thomas

Hallo Thomas,

ich dachte naiv, dass der SQL Server CE ziemlich gleich ist wie der normale SQL Server, mit welchem ich Erfahrungen habe. Es scheint aber etwas mehr abgespeckt zu sein.

Folgendes habe ich eben rausgegoogelt:

„Named parameters are not supported in SQL Server CE“

Man muss also mit den Fragezeichen im SQL-Statement arbeiten, welchen dann die SQL-Parameter in der Reihenfolge wie sie definiert wurden, zugeordnet werden.

Muster: INSERT INTO tabelle(f1, f2, f3, f4) VALUES (?, ?, ?, ?)

Ich weiss leider nicht wie sich es mit INSERT INTO tabelle (…) select(…) verträgt, würde es aber ausprobieren. Wenn es nicht klappt, kann man immer noch als Notlösung die Daten, welche in den neuen Datensätzen aus vorhandenen Datensätzen gespeichert werden, vorher im Programm zu ermitteln und dann reine Insert Statements mit festen Feldwerten zu nutzen.

Viele Grüße
Erich

Hallo Erich,

naja, benannte Parameter funktionieren eigentlich schon, zumindest in einfacheren Statements wie primitive INSERTs, UPDATEs und DELETEs.
Die Möglichkeit mit den Fragezeichen kannte ich noch nicht und werde sie mal ausprobieren.
Ansonsten kann ich natürlich, wie von Dir vorgeschlagen, einen Workaround programmieren, der erst die Daten aus dem zu kopierenden Datensatz liest.

Danke und schöne Grüße
Thomas