2013-10-09 3 views
1

У меня были эти две таблицы в базе данных SQL Server для приложения C#.Вставка в таблицу SQL Server на основе другой таблицы

---------------------------- 
table_Items 
---------------------------- 
Item1 | Item2| Item3 | Item4 
A  | B | C  | D 
E  | F | G  | Null 
H  | I | Null | Null 
J  | Null | Null | Null 

------------------ 
table_Item_Shelves 
------------------ 
Item_Name | Item_ID 
A  | Null 
B  | Null 
C  | Null 
D  | Null 
E  | Null 

Это то, что мне нужно было сделать. Для каждой строки в table_items сначала проверьте, имеет ли строка все значения (позиция 1,2,3,4) или три поля, , чем в таблице_Item_Shelves, вставьте '1' для каждого элемента в поле Item_ID. Для следующей строки выполните одну и ту же проверку и получите максимальное значение из поля Item_ID и увеличьте значение на 1. Мне также нужно проверить, что максимум четыре элемента Item_ID могут быть одинаковыми. Любая помощь в C# и SQL будет отличной. Благодарю.

Столбец table_Item_Shelves Item_ID уже имеет значение, чем я не должен вставлять новый ID table_Item_Shelves уже содержат записи, и мне нужно обновить эти записи.

CREATE PROCEDURE UpdateItemIDs КАК НАЧАТЬ ВЫБОР ROW_NUMBER (НАД) (ORDER BY item1) AS RowIndex, IT. *, 0 AS обрабатываются НА #TempTable ОТ dbo.table_items IT ГДЕ (Элемент1 НЕ NULL И Элемент2 НЕ NULL И item3 IS NOT NULL ) OR (Элемент1 IS NOT NULL И Элемент2 IS NOT NULL И item4 IS NOT NULL ) ИЛИ (Элемент1 НЕ NULL И Item3 IS NOT NULL И item4 IS NOT NULL ) OR (Элемент2 IS NOT NULL И Item3 IS NOT NULL И item4 IS NOT NULL )

 DECLARE @ITEM1 VARCHAR(50) 
     DECLARE @ITEM2 VARCHAR(50) 
     DECLARE @ITEM3 VARCHAR(50) 
     DECLARE @ITEM4 VARCHAR(50) 
     DECLARE @RowIndex INT 
     DECLARE @NewItemID INT 

     WHILE (SELECT COUNT(*) 
       FROM #TempTable 
       WHERE processed = 0 
      ) > 0 
      BEGIN 
       SELECT TOP 1 
         @ITEM1 = Item1 , 
         @ITEM2 = Item2 , 
         @ITEM3 = item3 , 
         @ITEM4 = Item4 , 
         @RowIndex = RowIndex 
       FROM #TempTable 
       WHERE processed = 0 

       UPDATE #TempTable 
       SET  processed = 1 
       WHERE RowIndex = @RowIndex 

       SET @NewItemID = (SELECT ISNULL(MAX(Item_ID), 0) + 1 
            FROM  dbo.table_items_shelves 
           ) ; 

       UPDATE dbo.table_items_shelves 
       SET  Item_ID = @NewItemID 
       WHERE Item_Name IN (@ITEM1, @ITEM2, @ITEM3, @ITEM4) 
         AND Item_ID IS NULL 
      END 
    END 

У меня есть это выше хранимая процедура, которая работает (с помощью кого-то), но мне нужно изменить ее для работы с 8 столбцами в table_items (Item1, Item2 ..... Item8) и проверить, имеет ли строка значения во всех (item1, item2 .... item8) или 5 полей, , чем в table_Item_Shelves, вставить '1' для каждого элемента в поле Item_ID. Для 8 столбцов в в table_items (ITEM1, ITEM2 ..... ст.8)

able_Items 
----------------------------------------------------------------------- 
Item1 | Item2 | Item3  | Item4 | Item5 | Item6 | Item7 | Item8 | 
------------------------------------------------------------------------ 
Pencils | Rubbers | Books  | DvDs | Glue |Stapler| CDs |Mouse | 
Marker |KeyChain |Clipboards |Pens |Bucket| Null | 
Monitors| Null | 
Glue | Null |Null | Null | Null | Null | Null | Null | Null | 
Papers| Null | Null | Null 



table_Item_Shelves 
------------------ 
Item_Name | Item_ID 
------------------- 
Pencils | Null 
Rubbers | Null 
Pens  | Null 
Books  | Null 
Staplers | Null 
Glue  | Null 
Buckets | Null 
Keyborads | Null 
Monitors | Null 
Mouse  | Null 
CDs  | Null 
DvDs  | Null 
Papers | Null 
Clipboards| Null 
Markers | Null 
KeyChains | Null 

Теперь из данных в таблицах При условии я ожидаю результатов что-то вроде этого

table_Items имеет значения во всех столбцах в строке 1,

В таблице нет Item_ID, поэтому для каждого элемента в строке 1 я вставляю '1'. Чем проверить Row 2, она имеет 5 пунктов поэтому для каждого элемента, я вставлю Макс (item_id) + 1.

< строка 3 5 и строка 4 < 5 и строки 5 < 5 столбцов со значениями и Его 3+ ROW 4 + ROW 5 также < 5, поэтому я игнорирую их. также если «Item_ID» не «NULL или Empty», я игнорирую столбец.

Конечный результат будет выглядеть следующим образом.

table_Item_Shelves 
------------------ 
Item_Name | Item_ID 
------------------- 
Pencils | 1 
Rubbers | 1 
Pens  | 2 
Books  | 1 
Staplers | 1 
Glue  | 1 
Buckets | 2 
Keyborads | Null 
Monitors | Null 
Mouse  | 1 
CDs  | 1 
DvDs  | 1 
Papers | Null 
Clipboards| 2 
Markers | 2 
KeyChains | 2 

Нет предложений по дизайну, пожалуйста, я знаю, что это ужасно. Благодарю.

+3

Возможно, вам стоит ознакомиться с «нормализацией данных», поскольку это может помочь вам в более общем смысле. Кажется, что есть некоторые недостатки дизайна (если я не понимаю более общий контекст ваших ограничений и приложений). –

+2

Не знаю, как выглядят ваши данные, но с моей головы это довольно забавный дизайн. Я бы предложил попробовать перевернуть его из одной строки до 8 столбцов до 8 строк с одним значением. – Andrew

+1

@ Andrew я забыл написать это раньше «Нет предложений дизайна, пожалуйста, я знаю, что это ужасно. Спасибо». Если бы я был таким умным, чтобы реализовать вашу идею, я бы не был здесь. Спасибо за вашу помощь. – mubi

ответ

0

Это может сработать.

using System; 

    using System.Collections.Generic; 

    using System.Data; 

    using System.Data.SqlClient; 

    using System.Linq; 

    using System.Text; 


    namespace InsertTeamIdIntoTable 

    { 

     class Program 

     { 

      const string str = @"Data Source=(localdb)\Projects;Initial Catalog=TestDb;Integrated Security=SSPI"; 

      static void Main(string[] args) 

      { 


       InsertItemData(str); 

      } 


      private static void InsertItemData(string connectionString) 

      { 

       string queryString = 

        "SELECT item1,item2,item3,item4 FROM dbo.table_items;"; 


       using (SqlConnection connection = 

          new SqlConnection(connectionString)) 

       { 

        SqlCommand command = 

         new SqlCommand(queryString, connection); 

        connection.Open(); 


        SqlDataReader reader = command.ExecuteReader(); 

        int itemId = 1; 

        //check if row has values in all(item 1,2,3,4) or three of the fields, 

        while (reader.Read()) 

        { 

         bool flag = CheckValueNumber((IDataRecord)reader); 

         if (flag) 

         { 


          for (int i = 0; i < ((IDataRecord)reader).FieldCount; i++) 

          { 

           string itemName = ((IDataRecord)reader)[i].ToString(); 

           if (string.IsNullOrWhiteSpace(itemName) == false) 

           { 

            if (CheckItemShelveExists(str, itemName)) 

            { 

             if (CheckItemIdExists(str, itemName) == false) 

             { 

              UpdateTableItemShelves(str, itemId, itemName); 

             } 

            } 

            else 

            { 

             InsertTableItemShelves(str, itemId, itemName); 

            } 

           } 

          } 

          itemId++; 

         } 

        } 

        reader.Close(); 

       } 

      } 


      public static void UpdateTableItemShelves(string connectionString, int itemId, string itemName) 

      { 

       string updateString = string.Format("Update dbo.table_item_shelves set item_id ={0} WHERE item_name ='{1}';", itemId, itemName); 


       using (SqlConnection connection = 

          new SqlConnection(connectionString)) 

       { 

        SqlCommand command = 

         new SqlCommand(updateString, connection); 

        connection.Open(); 


        command.ExecuteNonQuery(); 


       } 

      } 


      public static void InsertTableItemShelves(string connectionString, int itemId, string itemName) 

      { 

       string updateString = string.Format("Insert Into dbo.table_item_shelves(item_id,item_name) VALUES({0},'{1}');", itemId, itemName); 


       using (SqlConnection connection = 

          new SqlConnection(connectionString)) 

       { 

        SqlCommand command = 

         new SqlCommand(updateString, connection); 

        connection.Open(); 


        command.ExecuteNonQuery(); 


       } 

      } 



      public static bool CheckItemShelveExists(string connectionString, string itemName) 

      { 

       string updateString = string.Format("Select count(id) From dbo.table_item_shelves WHERE item_name ='{0}';", itemName); 


       using (SqlConnection connection = 

          new SqlConnection(connectionString)) 

       { 

        SqlCommand command = 

         new SqlCommand(updateString, connection); 

        connection.Open(); 


        return (Int32)command.ExecuteScalar() > 0; 


       } 

      } 


      public static bool CheckItemIdExists(string connectionString, string itemName) 

      { 

       string updateString = string.Format("Select item_id From dbo.table_item_shelves WHERE item_name ='{0}';", itemName); 


       using (SqlConnection connection = 

          new SqlConnection(connectionString)) 

       { 

        SqlCommand command = 

         new SqlCommand(updateString, connection); 

        connection.Open(); 

        SqlDataReader reader = command.ExecuteReader(); 


        while (reader.Read()) 

        { 

         if (string.IsNullOrWhiteSpace(((IDataRecord)reader)[0].ToString()) == false) 

         { 

          return true; 

         } 

        } 


        reader.Close(); 

        return false; 


       } 

      } 


      public static bool CheckValueNumber(IDataRecord record) 

      { 

       int count = 0; 

       for (int i = 0; i < record.FieldCount; i++) 

       { 

        if (string.IsNullOrWhiteSpace(record[i].ToString()) == false) 

        { 

         count++; 

        } 

       } 

       return count >= 3; 

      } 


     } 

    } 
0

Это немного трудно понять ваш желаемый конечный результат (без ожидаемого результата пример), но первая часть ваших процедур WHERE клауса может быть упрощенным резко, чтобы иметь дело с более полей более легко ...

-- OLD 
WHERE (Item1 IS NOT NULL 
       AND Item2 IS NOT NULL 
       AND item3 IS NOT NULL 
      ) 
      OR (Item1 IS NOT NULL 
       AND Item2 IS NOT NULL 
       AND item4 IS NOT NULL 
       ) 
      OR (Item1 IS NOT NULL 
       AND Item3 IS NOT NULL 
       AND item4 IS NOT NULL 
       ) 
      OR (Item2 IS NOT NULL 
       AND Item3 IS NOT NULL 
       AND item4 IS NOT NULL 
       ) 

используя дополнительный формат (дополнительные данные, чтобы разрешить выполнение запроса автономно)

Этот формат позволяет вам просто дублировать операторы CASE и изменять критерии по количеству допустимых полей.

WITH A AS (
    SELECT 'A' AS Item1, 'B' AS Item2, 'C' AS Item3, 'D' AS Item4 
    UNION ALL SELECT 'E', 'F', 'G', NULL 
    UNION ALL SELECT 'H', 'I', NULL, NULL 
    UNION ALL SELECT 'J', NULL, NULL, NULL 
), B AS (
    SELECT A.* 
     , ROW_NUMBER() OVER (ORDER BY Item1) AS RowIndex 
     , 0 AS processed 
     , CASE WHEN Item1 IS NULL THEN 0 ELSE 1 END 
      + CASE WHEN Item2 IS NULL THEN 0 ELSE 1 END 
      + CASE WHEN Item3 IS NULL THEN 0 ELSE 1 END 
      + CASE WHEN Item4 IS NULL THEN 0 ELSE 1 END 
      AS ValidFieldCount 
    FROM A 
) 
SELECT * 
FROM B 
WHERE ValidFieldCount >=3 
+0

Также можно просто поместить оператор CASE в предложение where непосредственно вместо подзапроса. – DarrenMB

+0

Пожалуйста, проверьте, имеет ли он сейчас немного больше смысла. – mubi

+0

Можно ли это сделать в C#. Если я могу создавать массивы для каждой строки и использовать эти значения для обновления второй таблицы? – mubi

Смежные вопросы