2010-12-29 3 views
2

私の雇用者のプライマリ・スキーマの3つのいずれかのために、ゆっくりとstartter changeSet xmlファイルを作成します。唯一のショーストッパーは、liquibaseによって管理される大規模なMySQLストアドプロシージャライブラリを組み込んでいます。JDBC w/liquibaseとMySQLのセッション変数とクライアント側のSQL命令の回避策があります

一つSPROCをに対処するために痛みを多少されています:最初のいくつかのステートメントは、

use TargetSchema; 
select "-- explanatory inline comment thats actually useful --" into vDummy; 

set @@session.sql_mode='TRADITIONAL' ; 

drop procedure if exists adm_delete_stats ; 

delimiter $$ 

create procedure adm_delete_stats(
...rest of sproc 

のように行って、私はその逆効果としてのuse文を切り出すが、本当の問題が原因set @@session.sql_mode文です

liquibase.exception.MigrationFailedException: Migration failed for change set ./foobarSchema/sprocs/adm_delete_stats.xml::1293560556-151::dward_autogen dward: 
Reason: liquibase.exception.DatabaseException: Error executing SQL ... 

ような例外そしてdelimiter文は別のつまずきです。

Doing do dilligence research私はこの拒否されたMySQLバグレポートhereとこの問題に深く関わるこのMySQLフォーラムスレッドhereを見つけました。

私は現在、Liquibaseに存在するsprocスクリプトを使用できますか?何百ものストアドプロシージャを書き直す必要がありますか?

set、delimiter、および同様のSQLコマンドが解釈され、クライアントサイドインタプリタによって実行されることを前提としているため、createProcedure、sqlFile、およびsql liquibaseタグを試しました。サーバーに配信されます。

答えて

4

はい、私の問題は、あなたのスクリプトは、JDBCにはない追加の機能を持つmysqlクライアントを介して実行されることを前提としていると思います。

Liquibaseは、文を区切り文字に分割します(デフォルトは;ただし、区切り文字属性で変更できます)。その後、各文をデータベースに送ります。デリミタとして$$を指定すると、 "delimiter $$"行を削除することができますが、その前の各行には ";"が必要です。 $$に置き換えられました。それ以外にも、@@セッション行のようなクライアント固有のSQLもあります。私はそれがクライアントを通らなければ不必要かもしれないと思うが、私はそれが何をしているか完全にはわからない。

作業手順を手に入れることができますが、書き直しが必要です。

手順をすべて書き直すのではなく、executeCommandというタグを使用すれば、mysqlクライアントを呼び出して既存のスクリプトを使用することができます。 liquibaseがあなたにupdateSQLモードのようないくつかのものを提供していて、mysqlクライアントがあなたのchangelogをどこからでも実行できるようにする必要がありますが、スクリプトを書き直す必要はありません。

+0

はあなたの努力のためのアップ票を与え、私は/区切り文ではなく@@ session.sql_modeをスクラップしますすることができます指令は非交渉可能な要件です。 MySQLの場合、MySQLには実際のエラー処理ロジックがないため、すべての警告をエラーとして扱うようにクライアントライブラリに指示します。sproc呼び出しの致命的なエラーはほとんど完全に失われるか、または低下することがあります。プロシージャの作成時にSQLモードをシフトすると、プロシージャはそのモードで実行されます。 – David

+0

それ以外の場合は、executeCommandを使用することをお勧めします。私がliquibaseをエンジニアリング部門のほぼすべてのマシンでセミポータブルに設定しているので、データベースのクレデンシャルはプライマリコールスクリプトに一時的にエクスポートする独立したスクリプトファイルにあります。 executeCommandプロセスが親のスコープを継承するかどうかを調べる必要があります。 – David

2

これが私の仕事:要するに http://comments.gmane.org/gmane.comp.db.liquibase.user/480

を、それは、この意見:

<changeSet id="123321-4" author="ehrhardt"> 
    <sql>DROP PROCEDURE IF EXISTS curdemo;</sql> 
    <sql splitStatements="false" stripComments="false"> 
    <![CDATA[ 
     CREATE PROCEDURE curdemo() 
     BEGIN 
     DECLARE done INT DEFAULT 0; 
     blah.. 
     blah.. 
     END; 
    ]]> 
    </sql> 
    <sql>call curdemo();</sql> 
</changeSet> 
関連する問題