Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
UPDATE mit einer Spalte 'Plan' läuft auf Fehler
Seebär
myCSharp.de - Member



Dabei seit:
Beiträge: 48
Herkunft: Hamburg

Themenstarter:

UPDATE mit einer Spalte 'Plan' läuft auf Fehler

beantworten | zitieren | melden

verwendetes Datenbanksystem: MS SQL SERVER 2008

Guten morgen,

ich lade Tabellen aus einer DB in ein DataTable und binde dieses an eine DataGridView.

Der User kann beliebige Änderungen vornehmen.

Diese werden dann mittels Knopfdruck an die DB überspielt.

Das klapp soweit auch schon sehr gut.

Nur bei einer Tabelle laufe ich auf einen Fehler.

Diese hat eine Spalte namens 'PLAN'.

Der Fehler läßtsich wie feolgt reproduzieren:

Server-Seite:

CREATE TABLE [dbo].[Test](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Plan] [nvarchar](29) NULL,
 CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

INSERT INTO Test
VALUES
('Ein Wert'),
('Noch ein Wert')

Client-Seite:


            public static void PlanError()
            {
                int changedRows = 0;
                OleDbCommand cmd = new OleDbCommand();
                OleDbConnection con = new OleDbConnection(@"Provider=SQLOLEDB.1;Data Source=server11;Integrated Security=SSPI;Initial Catalog=<Datenbankname>");                
                cmd.Connection = con;
                cmd.CommandText = "SELECT * FROM Test";

                OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);                
                DataTable dataTable = new DataTable();

                try
                {
                    adapter.Fill(dataTable);
                    DataRow dataRow = dataTable.NewRow();
                    // einen neuen Wert einfügen
                    dataRow["Plan"] = "Ganz neuer Wert";
                    dataTable.Rows.Add(dataRow);

                    OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter);
                    changedRows = adapter.Update(dataTable);
                }
                catch (Exception ex)
                {
                   System.Windows.Forms.MessageBox.Show(ex.Message);
                }
            }

Führt man die Methode 'PlanError' aus, so kommt folgende Fehler:
Fehler
Falsche Syntax in der Nähe des 'Plan'-Schlüsselworts.

Das vom CommandBuilder erzeugte Insert-Statement lautet

INSERT INTO Test (Plan) VALUES (?)

Führe ich den SQL-Befehl im Management-Studio aus, z.B.

INSERT INTO Test (Plan) VALUES ('Ganz neuer Wert')

bekomme ich auch obigen Fehler.

Es funktioniert aber, wenn ich den Spaltennamen 'Plan' in eckige Klammern setze.

INSERT INTO Test ([Plan]) VALUES ('Ganz neuer Wert')

Leider erzeugt der OleDbCommandBuilder das Insert-Statement ohne diese eckigen Klammern.

Deswegen meine Frage: Gibt es irgendwelche Einstellungen, die den OleDbCommandBuilder die Spaltennamen in eckige Klameern zu setzen?

Oder gibt es einen anderen Ansatz, das Problem zu lösen?

Die Tabellenstruktur und damit die Spaltenbezeichner sind vorgegeben und können nicht geändert werden.

Ich bin für jede Anregung dankbar!
private Nachricht | Beiträge des Benutzers
Schleifer
myCSharp.de - Member



Dabei seit:
Beiträge: 24

beantworten | zitieren | melden

Warum der Fehler kommt weiß ich nicht. Reproduzieren ließ er sich. (Auch wenn man das Insertstatement manuell setzt.)

Wenn du aber anstelle von OleDb System.Data.SqlClient nutzt, klappt alles.
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1.552
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Hallo Seebär,

du verwendest Reservierte Schlüsselwörter. Dies kann wie du siehst in die Hose gehen.
Bitte verwende diese NIE. Um jedoch Reservierte Schlüsselwörter verwenden zu können musst du wie du selbst herausgefunden hast die betroffene Spalte in [...] setzen.

Für eine Liste der Reservierten Schlüsselwörter siehe:
Reservierte Schlüsselwörter

p.s. auch in C# kann man eine Variable int nennen. Dies würde man dan

int @int = 5;
double @double = 4d;
double @if = @double + @int;
aber dies macht man einfach nicht. Dasselbe ist in SQL.


Gruß
Michael
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
Seebär
myCSharp.de - Member



Dabei seit:
Beiträge: 48
Herkunft: Hamburg

Themenstarter:

beantworten | zitieren | melden

Danke ersteinmal für die Antworten!

@Schleifer:

Mit dem Sql-Client bekomme ich irgendwie keine Verbindung zur Datenbank hin. Der SQL Server sowie alle Datenbanken liegen auf einen anderen Server.

Vielleicht habe ich da auch noch eine Wissenslücke.

Mein Connectionstring via OleDB lautet ja


OleDbConnection con = new OleDbConnection(@"Provider=SQLOLEDB.1;Data Source=server11;Integrated Security=SSPI;Initial Catalog=<Datenbankname>");
Wie müsste er denn für den Sql-Client lauten? Dan kann ich ja keinen Provider angeben...

@xxMUROxx:

Das mit den Schlüsselwörtern ist mir schon klar. Aber auf die Namensgebung der Tabellenspalten habe ich keinen Einfluss; sie kommen von extern und dürfen nicht geändert werden.

Und der Caommand-Builder generiert die INSERT-, DELETE- und UPDATE-Statements automatisch, so dass ich da leider auch nicht eingreifen kann.

Oder gibt es doch etwas, was ich ihm mitgeben kann, damit er die Feldnamen in exkige Klammern setzt?

Ich wollte mir eigentlich ersparen, die drei Kommandos selber zu schreiben - bis auf diesen blöden Fehler klappt ja der update-Befehl des Adapters vorzüglich!
private Nachricht | Beiträge des Benutzers
vagtler
myCSharp.de - Member



Dabei seit:
Beiträge: 66
Herkunft: Köln

beantworten | zitieren | melden

Helfen Dir die Eigenschaften QuotePrefix resp. QuoteSuffix weiter?
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1.552
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Zitat von Seebär
Wie müsste er denn für den Sql-Client lauten?
Am einfachtsten geht es mit den von DbConnectionStringBuilder erbenden Klassen bzw mit ConnectionString.com
Zitat von Seebär
Mit dem Sql-Client bekomme ich irgendwie keine Verbindung zur Datenbank hin.
Wie lautet der Fehler bzw Fehlercode?
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
Seebär
myCSharp.de - Member



Dabei seit:
Beiträge: 48
Herkunft: Hamburg

Themenstarter:

beantworten | zitieren | melden

@vagtler:

Die Eigenschaften hören sich schon interessant an.

Laut Hilfe gehören diese der Klasse SqlSyncAdapterBuilder an.

Kann ich diese denn überhaupt in meiner OleDB-Umgebung verwenden?

Und wenn ja, wie?
private Nachricht | Beiträge des Benutzers
Florian Reischl
myCSharp.de - Experte

Avatar #avatar-2880.jpg


Dabei seit:
Beiträge: 1.564
Herkunft: München

beantworten | zitieren | melden

Zitat von Seebär
Wie müsste er denn für den Sql-Client lauten? Dan kann ich ja keinen Provider angeben...
So:


SqlConnection con = new SqlConnection(@"Data Source=server11;Integrated Security=SSPI;Initial Catalog=<Datenbankname>");
Zitat von Seebär
Mit dem Sql-Client bekomme ich irgendwie keine Verbindung zur Datenbank hin. Der SQL Server sowie alle Datenbanken liegen auf einen anderen Server.
Wenn du mit OLEDB drauf kommst, kommst du garantiert auch mit dem nativen SQL Provider drauf.

Zu deinem eigentlichen Problem:
Der XYZCommandBuilder ist ein echter Performance-Killer, da er immer wieder die Tabellen-Informationen vom Server abfragen muss, bevor er die Commands erzeugen kann.
Verwende entweder einen O/R-Mapper, oder verwende Stored Procedures.

Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
private Nachricht | Beiträge des Benutzers
Seebär
myCSharp.de - Member



Dabei seit:
Beiträge: 48
Herkunft: Hamburg

Themenstarter:

beantworten | zitieren | melden

Tatsächlich, das hat nun super geklappt - und jetzt funktioniert auch das Update!

Scheint tatsächlich ein kleiner Bug in der OleDB-Umgebung zu sein...

O/R-Mapper ist Neugebiet für mich - hast Du vielleicht Quellen / Links, wo ich mich einlesen könnte?

Danke euch allen für die Hilfe!!
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1.552
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Entity Framework
NHibernate

Aber ich denke eine Suche in google hätte dies auch ergeben. Wir sind nämlich auch kein Linkgenerator
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10.006

beantworten | zitieren | melden

@Seebär:
Ja, ist ein Bug, F40 genannt.
Der Fehler der ca 40cm vor der Tastatur sitzt.

Wenn DU reservierte Wörter im Sql Benutzt, gibt es halt Fehler, und der OleDbAdapter ( wie alle DataAdapter ) bietet dir ja an, die Namen zu maskieren.

@Florian Reischl:
Seit wann sind ORMapper schneller als ein CommandBuilder?
Und SP sind nicht schneller als (richtig ) parametrisierte Queries.
Was bei mehreren Datensätzen die Zeit kostet ist die meist fehlende Transaction.
private Nachricht | Beiträge des Benutzers
Florian Reischl
myCSharp.de - Experte

Avatar #avatar-2880.jpg


Dabei seit:
Beiträge: 1.564
Herkunft: München

beantworten | zitieren | melden

Hi FZelle
Zitat von FZelle
@Florian Reischl:
Seit wann sind ORMapper schneller als ein CommandBuilder?
Und SP sind nicht schneller als (richtig ) parametrisierte Queries.
Was bei mehreren Datensätzen die Zeit kostet ist die meist fehlende Transaction.

Kommt natürlich immer auf die Verwendung an, aber normalerweise cached ein O/R-Mapper die Tabellendefinitionen, bzw. lädt sich diese aus entsprechenden Mapping-Files auf dem Client. Der CommandBuilder cached nix, jede einzelne Verwendung führt wieder zu einem unnötgen Server-Roundtrip um die Spalteninformationen abzufragen.

Ich hatte nicht gesagt, dass Prozeduren schneller sind. Ich sage nur, entweder ORM oder SPs. Nicht wegen der Geschwindigkeit, sondern weil ich von im Client zusammengebaute SQL Statements nichts halte wenn's nicht ordentlich gekapselt (unt getestet!) ist.

Grüße
Flo
Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.
private Nachricht | Beiträge des Benutzers