Benutzer mit den meisten Antworten
Liste im Select-Statement übergeben

Frage
-
Guten Morgen zusammen,
gibt es eine Möglichkeit eine Datatable in ein Select-IN-Statemant zu übergeben? Quasi nach diesem Schema...
Using con As New SqlClient.SqlConnection(_ConString) Dim cmd As New SqlClient.SqlCommand("SELECT * FROM tb_USER WHERE ID IN ("& Datatable &")", con) Dim da As New SqlDataAdapter(cmd) da.Fill(dt) End Using
Die übergebene Tabelle eine Liste mit Materialnummern aus SAP die zur Laufzeit immer neu geladen wird. Über einen DataView suche ich spezielle Materialnummern heraus und möchte diese dann an den SQL-Server übergeben. In der Vergangenheit hab ich mir einen String aus den ganzen Daten (10-20 Datensätze) zusammengebaut, bei 4000 Datensätzen wäre es etwas unschönen einen 3km langen String an die DB zu übergeben :-)
Beste Grüße
David
Antworten
-
Damit man diesen Thread als erledigt kennzeichnen kann, möchte ich hier nochmal die zusammengefasste Lösung anhand eines Beispiels vorstellen. Dies kann dann jeder für seine Anwendung individuell anpassen.
1. müssen wir auf dem SQL-Server die Tabelle, den Typ und ein paar Datensätze haben. Das ganze sollte in etwa wie folgt aussehen. Eine Datenbank sollte bereits vorhanden sein :-)
CREATE TABLE tb_user( ID INT IDENTITY(1,1) PRIMARY KEY, Vorname VARCHAR(50) NOT NULL, Nachname VARCHAR(50) NOT NULL ); GO CREATE TYPE tb_userType AS TABLE( ID INT, Vorname VARCHAR(50), Nachname VARCHAR(50) ); GO INSERT INTO tb_user (Vorname, Nachname) VALUES ('Holger','Schulz'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Michael','Schmidt'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Thomas','Hermann'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Dirk','Metzger'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Stefan','Rodos'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Martin','Leimbach'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Rafael','Krüger'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Sven','Hein'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Heinrich','Pezzo'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Alexander','Kollo');
Bei einem lokalen Server und der normalen Windows-Authentifikation sollte es nun passen. Für einen speziellen Benutzer müssen noch die Berechtigungen freigegebenen werden.
Nun habe ich eine simple Anwendung mit einem DataGridView erstellt und den folgenden Code in die Load Prozedur gelegt
Dim dt As New DataTable dt.Columns.Add("UserID", GetType(Integer)) dt.Columns.Add("Vorname", GetType(String)) dt.Columns.Add("Nachname", GetType(String)) dt.Rows.Add(1, "", "") dt.Rows.Add(3, "", "") dt.Rows.Add(6, "", "") dt.Rows.Add(9, "", "") Using con As New SqlClient.SqlConnection(My.Settings.TestDBConnectionString) Dim cmd As New SqlClient.SqlCommand("SELECT * FROM tb_User WHERE ID IN (SELECT ID FROM @MeineUser)", con) cmd.Parameters.AddWithValue("@MeineUser", dt) cmd.Parameters("@MeineUser").SqlDbType = SqlDbType.Structured cmd.Parameters("@MeineUser").TypeName = "tb_userType" Dim dt2 As New DataTable Dim da As New SqlClient.SqlDataAdapter(cmd) da.Fill(dt2) Me.DataGridView1.DataSource = dt2 End Using
Was hier passiert ist recht simpel. Ich erstelle eine Tabelle die so aussieht wie meine TYP-Tabelle auf dem SQL Server. Dort trage ich die ID und leere Namen und Nachnamen ein, da diese erstmal uninteressant sind. Im zweiten Schritt wird nach der Connection das SQL-Statement gebaut mit meiner @MeineUser Variable über welche ich gleich meine UsertTable übergebe.
Igg. war es das nun und man kann eine ganze Tabelle an den Server übergeben und das SELECT ... IN .... Statement nutzen. Hoffe es hilft dem ein oder anderem weiter :-)
Beste Grüße
David
- Als Antwort markiert David Stania Mittwoch, 29. August 2012 10:53
Alle Antworten
-
bei 4000 Datensätzen wäre es etwas unschönen einen 3km langen String an die DB zu übergeben :-)
Hallo David,
der IN (Transact-SQL) Operator ist in Hinsicht an Werten für die Liste limitiert, siehe dort unter "Hinweis"; dort steht nur wage "hohe Anzahl", aus Erfahrung ist beim SQL Server 2005 bei ~1000 bereits Schluß.
Andere Optionen:
- Mit einer temporären Tabelle arbeiten und dann mitSELECT * FROM tb_User WHERE ID IN (SELECT ID from #myTempTable)
abfragen.
- Siehe Table-Valued Parameters in SQL Server 2008 (ADO.NET)
-
-
Damit man diesen Thread als erledigt kennzeichnen kann, möchte ich hier nochmal die zusammengefasste Lösung anhand eines Beispiels vorstellen. Dies kann dann jeder für seine Anwendung individuell anpassen.
1. müssen wir auf dem SQL-Server die Tabelle, den Typ und ein paar Datensätze haben. Das ganze sollte in etwa wie folgt aussehen. Eine Datenbank sollte bereits vorhanden sein :-)
CREATE TABLE tb_user( ID INT IDENTITY(1,1) PRIMARY KEY, Vorname VARCHAR(50) NOT NULL, Nachname VARCHAR(50) NOT NULL ); GO CREATE TYPE tb_userType AS TABLE( ID INT, Vorname VARCHAR(50), Nachname VARCHAR(50) ); GO INSERT INTO tb_user (Vorname, Nachname) VALUES ('Holger','Schulz'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Michael','Schmidt'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Thomas','Hermann'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Dirk','Metzger'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Stefan','Rodos'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Martin','Leimbach'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Rafael','Krüger'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Sven','Hein'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Heinrich','Pezzo'); INSERT INTO tb_user (Vorname, Nachname) VALUES ('Alexander','Kollo');
Bei einem lokalen Server und der normalen Windows-Authentifikation sollte es nun passen. Für einen speziellen Benutzer müssen noch die Berechtigungen freigegebenen werden.
Nun habe ich eine simple Anwendung mit einem DataGridView erstellt und den folgenden Code in die Load Prozedur gelegt
Dim dt As New DataTable dt.Columns.Add("UserID", GetType(Integer)) dt.Columns.Add("Vorname", GetType(String)) dt.Columns.Add("Nachname", GetType(String)) dt.Rows.Add(1, "", "") dt.Rows.Add(3, "", "") dt.Rows.Add(6, "", "") dt.Rows.Add(9, "", "") Using con As New SqlClient.SqlConnection(My.Settings.TestDBConnectionString) Dim cmd As New SqlClient.SqlCommand("SELECT * FROM tb_User WHERE ID IN (SELECT ID FROM @MeineUser)", con) cmd.Parameters.AddWithValue("@MeineUser", dt) cmd.Parameters("@MeineUser").SqlDbType = SqlDbType.Structured cmd.Parameters("@MeineUser").TypeName = "tb_userType" Dim dt2 As New DataTable Dim da As New SqlClient.SqlDataAdapter(cmd) da.Fill(dt2) Me.DataGridView1.DataSource = dt2 End Using
Was hier passiert ist recht simpel. Ich erstelle eine Tabelle die so aussieht wie meine TYP-Tabelle auf dem SQL Server. Dort trage ich die ID und leere Namen und Nachnamen ein, da diese erstmal uninteressant sind. Im zweiten Schritt wird nach der Connection das SQL-Statement gebaut mit meiner @MeineUser Variable über welche ich gleich meine UsertTable übergebe.
Igg. war es das nun und man kann eine ganze Tabelle an den Server übergeben und das SELECT ... IN .... Statement nutzen. Hoffe es hilft dem ein oder anderem weiter :-)
Beste Grüße
David
- Als Antwort markiert David Stania Mittwoch, 29. August 2012 10:53