本当にあった怖い話しDB 編  2012/10/27 やきに駆動2.0  SQLWorld お だ
自己紹介織田 信亮(おだ しんすけ)大阪で開発者していますSQLWorld の代表ですhttp://d.hatena.ne.jp/odashinsuke/Twitter:@shinsukeoda
SQLWorld とはhttp://sqlworld.org/Twitter:@SQLWorld_JP次のような情報を発信しているコミュニティです  MS の RDBMS である「SQL Server」  もちろん他の DB の話しも!  正規...
注意書き特定の製品を挙げているように見えますが、最近よく使ってるからだけで他意はありません!体験談で公式資料は見つけれてません!
本当にあった怖い話し_DB 編その1:システム要件を満たしているのに動かない!その2:バインド変数が動かない!その3:トランザクションが異なる?!
ODP.NET 4 がシステム要件を満たしているのに動かないhttp://docs.oracle.com/cd/E16338_01/win.112/b66456/InstallSystemRequirements.htm#i1006191
ODP.NET 4 がシステム要件を満たしているのに動かない  実行環境   Windows XP SP3   .NET Framework 4 Client Profile   .NET 2系は未インストール   ODP.NET 4   標準...
using System;using Oracle.DataAccess.Client;class Program {  static void Main(string[] args) {    try {      Console.Write...
using System;using Oracle.DataAccess.Client;class Program {  static void Main(string[] args) {    try {      Console.Write...
ODP.NET 4 がシステム要件を満たしているのに動かない  回避策 (どれか一つでOK)    Windows Update から .NET 3.5 SP1 をイン    ストール    C++ の再頒布可能パッケージ をインストー    ...
バインド変数に長い文字列を指定すると動かない 某9i で発生!  10g, 11g では発生せずバインド変数の値が 2000文字(ASCII) 以上の物が複数存在するとエラーが発生ORA-01461:LONG値はLONG列にのみバインドできます。
create table TEST (  PK number(3,0) not null primary key,  CONTENT1 varchar2(4000),  CONTENT2 varchar2(4000),  CONTENT3 va...
バインド変数に長い文字列を指定すると動かない 回避策  9i を使わない  クエリ内で文字列結合を行い、1バインド変  数の文字数が大きくならないようにする
create table TEST (  PK number(3,0) not null primary key,  CONTENT1 varchar2(4000),  CONTENT2 varchar2(4000),  CONTENT3 va...
ストアド内で複数回呼び出しているファンクションのトランザクションが異なる 11g で発生 非常に複雑なストアド内で同じファンク ションを何回も参照している時に発生  cursor  共通テーブル式  with cte as (select ~)...
ストアド内で複数回呼び出しているファンクションのトランザクションが異なる cursor と 共通テーブル式を辞めても発 生 window 関数か union all を辞めると発 生しなかった window 関数と union all を使った...
サンプルクエリの説明FOO テーブル   マスタテーブルBAR_FUNC   FOO.HOGE_KBN が ‘1’ はエラー発生   FOO.HOGE_KBN が ‘2’ はエラーなしZOO_PROCEDURE   FOO、BAR_FUNC を...
-- FOO.HOGE_KBN = ‘1’ はエラー発生、’2’ はエラー発生せずupdate FOO set HOGE_KBN = 1/commit/select BAR_FUNC(~) from dual -- FOO.HOGE_KBN =...
ストアド内で複数回呼び出しているファンクションのトランザクションが異なる BAR_FUNC 内で、FOO テーブルのデータを 確認してみると…   エラーが起きる時は、何故か更新前のデー   タを参照している   トランザクション内のデータが見...
ストアド内で複数回呼び出しているファンクションのトランザクションが異なる 回避策  window 関数は削れなかったので、union  all を諦めて、2つのクエリに分けた。  本当に回避出来てるのか不明。  原因を探れていないので、本当に発...
まとめ変な書き方してるクエリを見つけても、バカにしない!テストは大事!意味の分からない事象にぶち当たっても泣かない!
ご清聴ありがとうございました
Upcoming SlideShare
Loading in …5
×

本当にあった怖い話し (やきに駆動 2.0)

1,876 views
1,752 views

Published on

やきに駆動 2.0 〜日本よ、これがHoge駆動だ〜
http://atnd.org/events/31268

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,876
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

本当にあった怖い話し (やきに駆動 2.0)

  1. 1. 本当にあった怖い話しDB 編 2012/10/27 やきに駆動2.0 SQLWorld お だ
  2. 2. 自己紹介織田 信亮(おだ しんすけ)大阪で開発者していますSQLWorld の代表ですhttp://d.hatena.ne.jp/odashinsuke/Twitter:@shinsukeoda
  3. 3. SQLWorld とはhttp://sqlworld.org/Twitter:@SQLWorld_JP次のような情報を発信しているコミュニティです MS の RDBMS である「SQL Server」 もちろん他の DB の話しも! 正規化/モデリング SQL/NoSQL
  4. 4. 注意書き特定の製品を挙げているように見えますが、最近よく使ってるからだけで他意はありません!体験談で公式資料は見つけれてません!
  5. 5. 本当にあった怖い話し_DB 編その1:システム要件を満たしているのに動かない!その2:バインド変数が動かない!その3:トランザクションが異なる?!
  6. 6. ODP.NET 4 がシステム要件を満たしているのに動かないhttp://docs.oracle.com/cd/E16338_01/win.112/b66456/InstallSystemRequirements.htm#i1006191
  7. 7. ODP.NET 4 がシステム要件を満たしているのに動かない 実行環境 Windows XP SP3 .NET Framework 4 Client Profile .NET 2系は未インストール ODP.NET 4 標準の Widows Update は適用済み .NET 3.5 SP1 は除く 例外発生!!
  8. 8. using System;using Oracle.DataAccess.Client;class Program { static void Main(string[] args) { try { Console.WriteLine(typeof(string).Assembly.FullName); Console.WriteLine(typeof(OracleConnection).Assembly.FullName); var connStr = “~"; using (var conn = new OracleConnection(connStr)) using (var cmd = new OracleCommand(@"select SYSDATE from dual", conn)) { conn.Open(); Console.WriteLine(cmd.ExecuteScalar()); } } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } Console.ReadKey(); }}
  9. 9. using System;using Oracle.DataAccess.Client;class Program { static void Main(string[] args) { try { Console.WriteLine(typeof(string).Assembly.FullName); 例外発生! Console.WriteLine(typeof(OracleConnection).Assembly.FullName); var connStr = “~"; using (var conn = new OracleConnection(connStr)) using (var cmd = new OracleCommand(@"select SYSDATE from dual", conn)) { -------------------------------------------------------------------------------- conn.Open(); mscorelib, Version=4.0.0.0, ... Console.WriteLine(cmd.ExecuteScalar()); Oracle.DataAccess, Version=4.112.3.0, ... } Oracle.DataAccess.Client.OracleConnection type iniitalize } catch (Exception e) { Console.WriteLine(e.Message); error .... Console.WriteLine(e.StackTrace); -------------------------------------------------------------------------------- } Console.ReadKey(); }}
  10. 10. ODP.NET 4 がシステム要件を満たしているのに動かない 回避策 (どれか一つでOK) Windows Update から .NET 3.5 SP1 をイン ストール C++ の再頒布可能パッケージ をインストー ル http://www.microsoft.com/ja-jp/download/details.aspx?id=5638 OTN Discussion Forums ODP.NET4 required .NET2.0? https://forums.oracle.com/forums/thread.jspa?thr eadID=2423728&stqc=true
  11. 11. バインド変数に長い文字列を指定すると動かない 某9i で発生! 10g, 11g では発生せずバインド変数の値が 2000文字(ASCII) 以上の物が複数存在するとエラーが発生ORA-01461:LONG値はLONG列にのみバインドできます。
  12. 12. create table TEST ( PK number(3,0) not null primary key, CONTENT1 varchar2(4000), CONTENT2 varchar2(4000), CONTENT3 varchar2(4000))/insert into TEST values (:PK, :CONTENT1, :CONTENT2, :CONTENT3)/drop table TEST/ 結果 CONTENT1 CONTENT2 CONTENT3 NG 4000文字 4000文字 4000文字 NG 2000文字 2000文字 0文字 OK 1999文字 2000文字 1999文字 OK 1999文字 4000文字 1999文字
  13. 13. バインド変数に長い文字列を指定すると動かない 回避策 9i を使わない クエリ内で文字列結合を行い、1バインド変 数の文字数が大きくならないようにする
  14. 14. create table TEST ( PK number(3,0) not null primary key, CONTENT1 varchar2(4000), CONTENT2 varchar2(4000), CONTENT3 varchar2(4000))/insert into TEST values ( :PK, :CONTENT1_1 || :CONTENT1_2 || :CONTENT1_3 || :CONTENT1_4, :CONTENT2_1 || :CONTENT2_2 || :CONTENT2_3 || :CONTENT2_4, :CONTENT3_1 || :CONTENT3_2 || :CONTENT3_3 || :CONTENT3_4)/drop table TEST/
  15. 15. ストアド内で複数回呼び出しているファンクションのトランザクションが異なる 11g で発生 非常に複雑なストアド内で同じファンク ションを何回も参照している時に発生 cursor 共通テーブル式 with cte as (select ~) window 関数 sum() over (partition by ~) union all
  16. 16. ストアド内で複数回呼び出しているファンクションのトランザクションが異なる cursor と 共通テーブル式を辞めても発 生 window 関数か union all を辞めると発 生しなかった window 関数と union all を使ったシン プルなストアドだと発生しなかった 再現するミニマムクエリを発見出来ず…
  17. 17. サンプルクエリの説明FOO テーブル マスタテーブルBAR_FUNC FOO.HOGE_KBN が ‘1’ はエラー発生 FOO.HOGE_KBN が ‘2’ はエラーなしZOO_PROCEDURE FOO、BAR_FUNC を参照 トランザクションテーブルを更新 FOO テーブルは更新しない
  18. 18. -- FOO.HOGE_KBN = ‘1’ はエラー発生、’2’ はエラー発生せずupdate FOO set HOGE_KBN = 1/commit/select BAR_FUNC(~) from dual -- FOO.HOGE_KBN = ‘1’ なのでエラー発生/update FOO set HOGE_KBN = 2/select BAR_FUNC(~) from dual -- FOO.HOGE_KBN = ‘2’ なのでエラー発生せず/rollback/call ZOO_PROCEDURE (~) -- FOO.HOGE_KBN = ‘1’ なのでエラー発生/update FOO set HOGE_KBN = 2/call ZOO_PROCEDURE (~) -- FOO.HOGE_KBN = ‘2’ なのにエラー発生!!/
  19. 19. ストアド内で複数回呼び出しているファンクションのトランザクションが異なる BAR_FUNC 内で、FOO テーブルのデータを 確認してみると… エラーが起きる時は、何故か更新前のデー タを参照している トランザクション内のデータが見れていない
  20. 20. ストアド内で複数回呼び出しているファンクションのトランザクションが異なる 回避策 window 関数は削れなかったので、union all を諦めて、2つのクエリに分けた。 本当に回避出来てるのか不明。 原因を探れていないので、本当に発生しないのか は不明。 テストでは再現しなかった。
  21. 21. まとめ変な書き方してるクエリを見つけても、バカにしない!テストは大事!意味の分からない事象にぶち当たっても泣かない!
  22. 22. ご清聴ありがとうございました

×