0
#include <iostream>
#include <mysql++.h>
using namespace std;

int main() {
    // Get database access parameters from command line
    const char* db = "enet", *server = "192.168.1.108", *user = "root", *pass =
            "123456";
    // Connect to the sample database.
    mysqlpp::Connection conn(false);
    conn.set_option(new mysqlpp::MultiStatementsOption(true));
    if (conn.connect(db, server, user, pass)) {
        mysqlpp::Query query = conn.query();
        query << "call CreateTable('test1', 'generic', 0, 1, 2, 3,4,5,6,7,8,9,10,NOW());";
        query.execute();
        query.reset();

        query << "call CreateTable('test2', 'generic', 0, 1, 2, 3,4,5,6,7,8,9,10,NOW());";
        query.execute();
        query.reset();

        return 0;
    } else {
        cerr << "DB connection failed: " << conn.error() << endl;
        return 1;
    }

    return 0;
}

mysql ++クエリを使用してプロシージャ「CreateTable」を何度も実行したいのですが、最後にクエリをリセットしましたが、最初のクエリだけが機能し、最後のクエリは機能しません。問題は、すべてのクエリを作成する方法です。仕事?

-- create table --
delimiter $$
drop procedure if exists CreateTable $$
create procedure CreateTable(
    IN tableName VARCHAR(20), 
    IN dbName VARCHAR(20),
    IN INT_RegDevID INTEGER,
    IN Dec_Long DECIMAL(24,16),
    IN Dec_Lat DECIMAL(24,16),
    IN Dec_Height DECIMAL(10,6),
    IN Dec_Direction DECIMAL(10,6),
    IN AverageSpeed DECIMAL(10,6),
    IN Dec_Base VARCHAR(10),
    IN MCC INTEGER,
    IN MNC INTEGER,
    IN LAC INTEGER,
    IN CI INTEGER,
    IN Dec_LocaDate TIMESTAMP)
-- -------------------------------------------------------------------------------
-- -------------------------------------------------------------------------------
begin
    -- the test variable
    -- Warning: the encoding can result many problem!!!
    declare varTableName VARCHAR(32) default NULL;
    set @varTableName = NULL;
    set @table_prefix = "posinfo_";
    set @table_params = "(
          `Int_LocaID` int(11) NOT NULL auto_increment,
          `INT_RegDevID` int(11) NOT NULL default '0',
          `Dec_Long` decimal(24,16) NOT NULL default '0.0000000000000000',
          `Dec_Lat` decimal(24,16) NOT NULL default '0.0000000000000000',
          `Dec_Height` decimal(10,6) NOT NULL default '0.000000',
          `Dec_Direction` decimal(10,6) NOT NULL default '0.000000',
          `Dec_ MaxSpeed` decimal(10,6) NOT NULL default '0.000000',
          `Dec_ MinSpeed` decimal(10,6) NOT NULL default '0.000000',
          `AverageSpeed` decimal(10,6) NOT NULL default '0.000000',
          `Var_PosInfo` varchar(50) character set latin1 NOT NULL default '',
          `Var_Remark` varchar(200) character set latin1 NOT NULL default '',
          `Date_LocaDate` timestamp NOT NULL default CURRENT_TIMESTAMP,
          `Dec_Base` varchar(10) character set latin1 NOT NULL,
          `MCC` int(11) NOT NULL COMMENT '',
          `MNC` int(11) NOT NULL COMMENT '',
          `LAC` int(11) NOT NULL COMMENT '',
          `CI` int(11) NOT NULL COMMENT '',
          PRIMARY KEY  (`Int_LocaID`)
        ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=gbk;";
    set @varCreate = CONCAT("create table ", dbName,".",@table_prefix, tableName, @table_params);
    -- the insert operation
    set @insertOperation = CONCAT("insert into ", dbName,".",@table_prefix, tableName,
        "(INT_RegDevID,Dec_Long,Dec_Lat,Dec_Height,Dec_Direction,AverageSpeed,
         Dec_Base,MCC,MNC,LAC,CI,Date_LocaDate) values(",INT_RegDevID,",",Dec_Long,
         ",",Dec_Lat,",",Dec_Height,",",Dec_Direction,",",AverageSpeed,",",Dec_Base,
         ",",MCC,",",MNC,",",LAC,",",CI,",NOW())"); 
    -- find the target table
    -- Look care about the "' '" !
    set @getTargetTable = CONCAT("select TABLE_NAME into @varTableName from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='",
        dbName, "' and TABLE_NAME='", @table_prefix, tableName,"'");

    -- -------------------------------------------------------------------------------
    -- -------------------------------------------------------------------------------
    PREPARE getTargetTable from @getTargetTable;
    execute getTargetTable;
    select @varTableName;
    set varTableName = @varTableName;

    if varTableName is NULL then
        -- create new table
        PREPARE newTable 
        from @varCreate;
        execute newTable;
        -- do insert operation
        PREPARE insertOperation
        from @insertOperation;
        execute insertOperation;

    else
        -- do insert operation
        PREPARE insertOperation
        from @insertOperation;
        execute insertOperation;
    end if;

end $$
delimiter ;

上記の手順です。

4

1 に答える 1

1

ここにはいくつかのバグがあります:

  1. 例外()をオフにしましたがconn(false)、エラーコードの戻り値もチェックしていません。2番目のexecute()呼び出しは失敗しますが、オブジェクトに理由を尋ねずに、Queryブラインドで実行しています。

    conn()ただし、すべてのMySQL ++呼び出しにエラーチェックを追加する代わりに、MySQL ++が例外( )をスローし、すべてをブロックにラップできるようにする方がクリーンだと思いますtry

  2. MultiStatementsOptionあなたはあなたが現在示している方法であなたが求めていることをする必要はありません。ここには、1つの複合ステートメントではなく、2つの別個のステートメントがあります。これをセミコロンと組み合わせると、MySQLが混乱する可能性があります。そのため、2番目の呼び出しは失敗します。

    コマンドラインツールではmysql、SQLステートメントを終了するためにセミコロンが必要ですが、MySQL ++などのデータベースAPIを使用する場合は、複数のステートメントを区切るだけで済みます。

    両方のCREATEステートメントを1つの文字列(および1つexecute())に結合するか、セミコロンとを削除することができますMultiStatementsOption

  3. MySQL ++ 2. x以降、クエリ間のreset()呼び出しは必要ありません。このメソッドがまだ利用できる唯一の理由は、テンプレートクエリに使用されたオブジェクトを再利用する場合に必要だからです。かなり明白な理由で、まだ自動リセットされないタイプはこれらだけです。Query

于 2011-03-08T18:12:17.570 に答える