Flex: sqlite last_insert_rowid для нескольких вызовов вставки - PullRequest
1 голос
/ 22 сентября 2010

У меня есть файл с несколькими SQL-операторами, которые должны быть выполнены.

INSERT INTO reports (a,b,c) VALUES (1,2,3);

INSERT INTO units (report_id, e, f, g) VALUES ( (SELECT last_insert_rowid() FROM reports), 4, 5, 6);

INSERT INTO elements (report_id, h, i, j) VALUES ( (SELECT last_insert_rowid() FROM reports), 7, 8, 9);

Раздел ОТ отчетов подвыбора ничего не делает.

Чтов конечном итоге происходит следующее:

  1. В отчеты вставляется строка, а поле reports.id автоматически инкрементируется
  2. В блоки вставляется строка, в которой report_id равен id отчета
  3. В элементы вставляется строка, в которой report_id равен unit.id последней вставленной строки

Это работает, как описано в документации по sqlite.

Моя проблемав том, что я хочу, чтобы все запросы после вставки отчета использовали report.id.

Есть ли в любом случае, я могу заставить это работать на стороне базы данных, не прибегая к решению в as3?

1 Ответ

2 голосов
/ 22 сентября 2010

Есть способ сделать это, но он есть в AS3 с использованием параметров.

Вместо того, чтобы использовать функцию SELECT last_insert_row () при каждом вызове, замените ее параметром.

INSERT INTO elements (report_id, h, i, j) VALUES (@id, 7, 8, 9);

Теперь в моем коде мне нужно разделить файл на массив, чтобы каждый отдельный запрос обрабатывался отдельно (так AS3 реализует API sqlite).

var sqlArray:Array = sql.split(";\n\n");

Теперь, что яdo - выполнить первый оператор для импорта самого отчета.

statement.text = sqlArray[0];
statement.execute();

Теперь самое интересное.Вы должны получить идентификатор обратно.Таким образом, мы запускаем другой запрос.

statement.text = "SELECT last_insert_rowid() as ID";
statement.execute();
var id:int = statement.getResult().data[0].id;

Теперь мы можем перебрать остальные запросы, используя идентификатор в качестве параметра.

for(var i:int = 1; i < sqlArray.length - 1; i++) { 
  /**
   * start at 1 because we already inserted the report
   * end at length -1 because our last entry is empty because of how split works on our data
   **/
  statement.text = sqlArray[i];
  statement.parameters['@ID'] = id;
  statement.execute();
}

Это немного сложнее, но немного, и это в конечном итоге работает.

Все объединено в одну функцию (исключая много накладных расходов класса) будет:

function importFromSQLString(sql:String):void {
  try{
    connection.begin();
    var sqlArray:Array = sql.split(";\n\n");
    statement.text = sqlArray[0];
    statement.execute();

    statement.text = "SELECT last_insert_rowid() as ID";
    statement.execute();
    var id:int = statement.getResult().data[0].id;

    for(var i:int = 1; i < sqlArray.length - 1; i++) { 
      statement.text = sqlArray[i];
      statement.parameters['@ID'] = id;
      statement.execute();
    }
    connection.commit();
    statement.clearParameters();
  } catch (e:Error) {
    connection.rollback(); //cleanup if there was a failure
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...