2017-12-16 16 views
1

Ich habe 14 Tabellen von verschiedenen Arten von Mitarbeitern. Ich habe eine C# -Anwendung, die mit meiner SQL Server-Datenbank verdrahtet ist, und wenn ich einen Nachnamen in ein Textfeld eingabe, bringt es einen Datensatz mit diesem Nachnamen zurück und zeigt es in einer Listbox an.Abrufen bestimmter Werte aus mehreren Tabellen

Allerdings habe ich es mit nur einer Tabelle geschafft. Also, wenn ich "Jones" tippe, wird es zurückkommen und Jones von einem Tisch aus anzeigen.

Ich möchte alle Jones 'aus allen 14 Tabellen zurückbringen. Mit anderen Worten, wenn ich einen Nachnamen eintippe, brauche ich die Anwendung, um mir alle Datensätze dieses Nachnamens aus allen 14 Tabellen anzuzeigen.

Was wäre ein vernünftiger Ansatz dazu? Es wäre viel einfacher, wenn ich einen Tisch mit allen Angestellten hätte, aber ich brauche die Trennung. Grundsätzlich, wenn ich auf den Suchknopf klicke, brauche ich die Anwendung, um von irgendeinem der 14 Tische mit dem gegebenen Namen zu holen.

Was wäre ein geeigneter Ansatz dazu?

+0

Warum brauchen Sie die Trennung? Sie könnten eine Ansicht erstellen, die die 14 Tabellen zusammenführt, aber eine Tabelle hat, die für die Leistung viel besser ist. –

+0

Nun wollte ich das Personal in Kategorien eingeteilt, weil ich nicht weiß, wie ich die App später erweitern werde. Mir gefiel die Vorstellung von Vertrieb, Technik, Managern usw., anstatt alle Kategorien und alle Mitarbeiter in einer Kategorie zu haben. Ich verstehe, was du sagst, aber ich muss eine gemeinsame Basis für all diese Leute schaffen. –

+1

@NikosKap warum nicht einfach die Kategorie für jeden Benutzer zuweisen, anstatt Tabelle für jede Kategorie zu erstellen? – Neir0

Antwort

0

definieren Sie die folgende gespeicherte Prozedur in der Datenbank:

CREATE PROCEDURE GetAll_SP 
(
    @FirstName VARCHAR(50) 
) 
AS 
    BEGIN 
     (SELECT 1, first_name, last_name FROM UsersTable1 WHERE first_name = @FirstName) 
     UNION 
     (SELECT 2, first_name, last_name FROM UsersTable2 WHERE first_name = @FirstName) 
     UNION 
     (SELECT 3, first_name, last_name FROM UsersTable3 WHERE first_name = @FirstName) 
     -- .... 
    END 

GO 

oder die folgenden statt Sie nicht brauchen, um jede Art von Kontrolle über die Benutzer Standort hat:

CREATE PROCEDURE GetAll_SP 
(
    @FirstName VARCHAR(50) 
) 
AS 
    BEGIN 
     (SELECT first_name, last_name FROM UsersTable1 WHERE first_name = @FirstName) 
     UNION ALL 
     (SELECT first_name, last_name FROM UsersTable2 WHERE first_name = @FirstName) 
     UNION ALL 
     (SELECT first_name, last_name FROM UsersTable3 WHERE first_name = @FirstName) 
     -- .... 
    END 

GO 

Dann im Code:

String firstName = "Jones"; 

using (SqlCommand cmd = new SqlCommand("GetAll_SP", m_Connection)) 
{ 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Add("@FirstName", SqlDbType.VarChar).Value = firstName; 

    m_Connection.Open(); 
    cmd.ExecuteNonQuery(); 
} 
+0

Sieht gut aus. Ich werde es versuchen und es überprüfen. Ich muss jedoch ein paar Änderungen in meiner C# machen, weil ich Listen und Dapper verwende, also sollte es interessant sein. Ich werde es dir danken. –

+0

Schön. Es funktionierte. –

0

Sie sollten Ihren Code 14 Times wiederholen, um Werte aus allen diesen Tabellen zu sammeln, oder Sie senden eine SQL-Abfrage für alle 14 Tabellen gleichzeitig mit Unionen oder 14 Abfragen in einer Anweisung -

+0

Kann ich eine gespeicherte Prozedur mit 14 Suchvorgängen hinzufügen und dann die gespeicherte Prozedur in der App aufrufen? Ist das sinnvoll? –

+0

Ja das ist auch in Ordnung. Gespeicherte Prozeduren sind sehr schnell ... – Markus

+0

Ok, ich werde das ausprobieren und zurückschauen. –

0

okay, aus allen 14 Tabellen erhalten Ergebnisse, die Sie UNION ALL Operator verwenden können, so würde Ihre SQL etwas wie folgt aussehen:

(SELECT first_name, last_name FROM table1 WHERE first_name='John') 
UNION ALL 
(SELECT first_name, last_name FROM table2 WHERE first_name='John') 
... 
(SELECT first_name, last_name FROM table14 WHERE first_name='John') 

Sie müssen die gleiche Menge von Feldern haben in jeder wählen. Ein besserer Ansatz wäre jedoch, wenn Sie alle Namen (und alle anderen gemeinsam genutzten Daten) in einer Tabelle speichern und eine Verbindung mit Key mit all diesen 14 Tabellen herstellen, die unterschiedliche Datenmengen haben. So können Sie eine so lange Abfragen wie diese oben verhindern kann (und wahrscheinlich langsame Abfragen) und Abfrage würde aussehen wie folgt aus:

SELECT first_name, last_name, user_type, user_id WHERE first_name='John' 

Und dann können Sie Felder retreive aus der Tabelle entspricht, wie Feld user_type gibt Ihnen Informationen in die aus 14 Tabellen für andere Daten zu suchen und user_id gibt Ihnen Daten des Benutzers, so zweite Abfrage würde wie folgt aussehen:

SELECT job_position, worksheet, other_data FROM tableN WHERE user_id=... 
0

Einfach gesetzt @SearchStr und Jede Spalte in jeder Tabelle wird durchsucht.

drop table #results 
go 

declare @SearchStr nvarchar(100) 
set @SearchStr = 'Donna%' -- use wildcards 

CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630)) 

SET NOCOUNT ON 

DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110) 
SET @TableName = '' 
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''') 

WHILE @TableName IS NOT NULL 
BEGIN 
    SET @ColumnName = '' 
    SET @TableName = 
    (
     SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)) 
     FROM INFORMATION_SCHEMA.TABLES 
     WHERE  TABLE_TYPE = 'BASE TABLE' 
      AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName 
      AND OBJECTPROPERTY(
        OBJECT_ID(
         QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) 
         ), 'IsMSShipped' 
          ) = 0 
    ) 

    WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL) 
    BEGIN 
     SET @ColumnName = 
     (
      SELECT MIN(QUOTENAME(COLUMN_NAME)) 
      FROM INFORMATION_SCHEMA.COLUMNS 
      WHERE  TABLE_SCHEMA = PARSENAME(@TableName, 2) 
       AND TABLE_NAME = PARSENAME(@TableName, 1) 
       AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'text') 
       AND QUOTENAME(COLUMN_NAME) > @ColumnName 
     ) 

    print cast(@TableName as nvarchar(200)) + ' ' + @ColumnName 

    IF @ColumnName IS NOT NULL 
     BEGIN 
      INSERT INTO #Results 
      EXEC 
      (
       --'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630) 
       --FROM ' + @TableName + ' (NOLOCK) ' + 
       --' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 

       'SELECT ''' + @TableName + '.' + @ColumnName + ''', ' + @ColumnName + ' 
       FROM ' + @TableName + ' (NOLOCK) ' + 
       ' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2 
      ) 
     END 
    END 
END 

SELECT ColumnName, ColumnValue FROM #Results 
Verwandte Themen