2016-10-11 2 views
0

Так что я пытаюсь получить данные из одной таблицы (table1), а затем записывать выбранные данные во вторую таблицу (таблица2). Я могу получить данные из таблицы1 и выбрать нужные данные. У меня возникли проблемы с записью его на стол2.F # SqlCommand динамически писать в таблицу SQL

Это то, что я имею на данный момент:

let insertData(data: string []List) = 

    let tableName = data.Item(0).GetValue(0).ToString() //Gets the table Name 
    let columnTypes = GetDevTableColumnsTypes tableName 

    let mutable tableDataTemp = List.empty 
    for i = 0 to data.Length-1 do 
     let mutable rowDataTemp = List.empty 

     for j = 0 to data.Item(i).Length-1 do 
      if data.Item(i).GetValue(j).Equals(tableName) then //if statement removes table name from string array. 
       System.Diagnostics.Debug.WriteLine("tableName removed from data") 
      else 
       let cellData = data.Item(i).GetValue(j) 

       rowDataTemp <- cellData :: rowDataTemp 

     let rowData = rowDataTemp |> List.toArray |> Array.rev 
     tableDataTemp <- rowData :: tableDataTemp 

    let tableData = tableDataTemp |> List.toArray |> Array.rev //Probably unneeded 

    let cn = new SqlConnection(Settings.Azure.SQL.CCSettingDev) 
    cn.Open() 
    let sQL = "INSERT INTO [" + tableName + "] VALUES(@param1)" 
    let db = new SqlCommand(sQL, cn) 
    db.Parameters.AddWithValue("@param1", tableData) 
    db.ExecuteNonQuery() 

Когда я запускаю код я получаю этот аргумент исключением указал на ExecuteNonQuery:

Исключение типа «System.ArgumentException» произошло в System.Data.dll, но не обрабатывался в коде пользователя

Дополнительная информация: Состояния объектов из System.Object [] в известный тип управляемого управляемого провайдера отсутствует.

Теперь на данный момент я работаю только с 2 таблицами, но вскоре программа будет работать с несколькими таблицами с разными именами столбцов, поэтому мне нужно, чтобы это работало независимо от таблицы, в которую она пишет. table1 и table2 имеют одинаковые столбцы. таблицы 3 и 4 имеют одинаковые столбцы друг с другом, но они имеют разные столбцы для таблиц 1 и 2.

selectedData - массив объектов, который содержит другие массивы объектов.

Если вы считаете, что лучше добавить данные вместо добавления массива, пожалуйста, дайте мне знать.

Любая помощь будет оценена по достоинству.

+2

Я настоятельно советую что вы пересматриваете этот метод. Это простой старый изменяемый код, который делает ввод данных уродливым способом. Этот код был бы плохим в C#. F # ничего не предлагает. Зачем использовать 'GetValue' для получения элемента массива? Зачем использовать 'ToString()', когда массив уже * является строковым массивом? Зачем передавать как имя таблицы *, так и * значения полей в одном массиве? Что это за код? –

+1

Пожалуйста, объясните, какова ваша фактическая бизнес-проблема, а не как вы ее пытались решить. Похоже, вы хотите СМЯТЬ список записей в таблицу? Или вставить только новые записи? Напишите инструкцию 'INSERT ... WHERE', которая объединяется с параметром table и вставляет только новые записи. Передайте параметр таблицы как DataTable. –

+0

, если вы ссылаетесь на первую строку data.GetValue (0) .ToString(). Когда я удаляю tostring, tableName становится obj и, следовательно, несовместим. То, что оно передано (данные), - это имя таблицы плюс числовая ссылка на точку в массиве. Поэтому скажем, что пройденное число равно 2. Это означает, что я хочу 3-е значение в existInTable1. У меня есть массив obj, где я хочу добавить значения в массив ко второй таблице. Я должен был упомянуть, что вся программа - это web api –

ответ

0

пусть сп = новый SqlConnection (ConnectionString) cn.Open()

for i=0 to tableData.Length-1 do 
    let mutable columnsTemp = "" 
    let mutable valuesTemp = "" 
    for j = 0 to tableData.Item(i).Length-2 do 
     columnsTemp <- columnsTemp + columnNames.GetValue(j).ToString() + "," 
     valuesTemp <- valuesTemp + "'" + tableData.Item(i).GetValue(j).ToString() + "'," 


    let columns = columnsTemp.Remove(columnsTemp.Length-1,1) 
    let values = valuesTemp.Remove(valuesTemp.Length-1,1) 
    let sQL = "INSERT INTO [" + tableName + "] (" + columns + ") VALUES (" + values + ")" 
    let db = new SqlCommand(sQL, cn) 
    db.ExecuteNonQuery() 
0

Вам необходимо использовать table-valued parameter. Я думаю, что здесь самый простой способ будет конвертировать chosenData в массив SqlDataRecord, а затем сделать

let sQL = "INSERT INTO [" + tableName + "] SELECT * FROM @param1" 
+1

Этого недостаточно. OP передает список вместо DataTable –

+0

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

+1

@JacksonSentzke вы не можете этого сделать. Какой объект окажется в столбце? Во всяком случае, самый простой способ вставить данные - использовать SqlBulkCopy, передать ему DataTable (который * не * жестко запрограммирован) и гарантировать, что столбцы данных соответствуют именам столбцов таблицы. Вставьте данные во временную таблицу, а затем объедините их в финальную таблицу. –

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