hkoba blog

プログラマーです。プログラミング言語ミーハーです。ツッコミ歓迎です。よろしくどうぞ(能代口調)

実験: SQLite の `in (...)` 句を *雑に* zsh の配列展開で生成してみる

はじめに

  • ツッコミ歓迎です。
  • 対象DB は SQLite です。
  • あくまで入力データの特性を完全に把握しコントロール出来る場合しかおすすめしません…

値に single quote (') が入らない保証が有る場合

% values=(
  foo
  bar
  baz
)
% print " in (${(j/,/)"${(@qq)values}"})"
 in ('foo','bar','baz')
% 

こっちは割と、仕事で使ってます。

解説

  • ここでは配列変数 values に値を格納
  • @qq は配列の要素ごとに qq (single quote で囲む) を適用
    • それを一旦 " " で囲むことで、 "$@" と同じ効果を出す
  • j/,/ は配列を , で join.

値に single quote も入る可能性が有る場合

qq フラグで自動 quote させる場合、文字列中の single quote は '\'' という文字列に置換される

% foo="Foo's Bar"
% print -r ${(qq)foo}
'Foo'\''s Bar'
%  

これを '' に置き換えれば行けるのではないか…

% values=(foo bar "Foo's Bar")
% print -r "in (${${(j/, /)${(@qq)values}}//'\''/''})"
in ('foo', 'bar', 'Foo''s Bar')
%

出来た気がする…

追記2018-05-08+:配列じゃなくてスカラーの場合の書き方、コピペ用

実務でよく使うようになったので、これも。

% foo="Foo's Bar"
% print -r "${${(qq)foo}//'\''/''}"
'Foo''s Bar'
%

関数にまとめるとこうかしら?

function zqsql {
  local val=$1
  print -nr "${${(qq)val}//'\''/''}"
}