アプリ版:「スタンプのみでお礼する」機能のリリースについて

Wordpressにあるusermetaというテーブルに、
別のDBのテーブルからデータをINSERTしたいのですが、
#1241 - Operand should contain 1 column(s) というエラーが表示されてうまくいきませんでした。

具体的なSQL文は、

insert into ***_usermeta (umeta_id,user_id,meta_key,meta_value)
select
(null,tableBid,'first_name',''),
(null,tableBid,'last_name',''),
(null,tableBid,'nickname',tableBname),
(null,tableBid,'***_capabilities','a:1:{s:10:\"subscriber\";b:1;}'),
(null,tableBid,'***_user_level','0')
from dbB.tableB where tableBname<> 'Admin'

dbBのtableB にあるAdmin行以外を対象としています。
実際にはもう少しデータが多いのですが、select (null,uid,'first_name','') from ・・・
だけにしても同じエラーが出ましたので、構文の書き方が間違っていると感じています。
(別のDBではなく、同じDBの別のTableからのINSERTでも同じエラーが表示されました)

上記のようなケースの場合、どのようにSQL文を書けばよいのでしょうか?
お分かりになられる方がいらっしゃいましたら、ご教示頂けますと幸いです。
宜しくお願い致します。

A 回答 (3件)

1.select文の カラムリストに () 付けで、複数行データ定義などと言うことはできません。


union all を使ってください。

2.まずは、select 文だけ書いてみてエラーのない select 文になれば、insert につないで実行可能です。
No1回答への補足をみると 1対1対応させるのは、できてるのですね。

3. umeta_idカラムが auto_increment だからnull を入れているなら、カラムリストから外しても良いと思います
insert into ***_usermeta (user_id,meta_key,meta_value)
select tableBid,'***_user_level','0'
from dbB.tableB where tableBname <> 'Admin'
union all
select tableBid,'nickname',tableBname
from dbB.tableB where tableBname <> 'Admin'

4. dbB.tableB の一行に対して、5行(以上)作って順番指定したいのですね。
5行用のデータを union all で繋いで作ったtableを join しましょう。

select b.tableBid as user_id, k.meta_k as meta_key, COALESCE( k.meta_v , b.tableBname ) as meta_value
from
( select tableBid, tableBname
from dbB.tableB where tableBname <> 'Admin'
) as b
cross join
( select 'first_name' as meta_k, '' as meta_v , 1 as order_no
union all select 'last_name', '' , 2
union all select 'nickname', null, 3
union all select '***_capabilities','a:1:{s:10:\"subscriber\";b:1;}' , 4
union all select '***_user_level','0' , 5
) as k
order by b.tableBid, k.order_no
;

上記のtable記述順でcross join するなら、order by は無くても、希望の順番にはなりそうですけど、一応いれておきました。
このselect文で、insert したい行が生成できているならば、あとは先頭にinsert 用の構文(3で提示の1行目)を繋げばよいでしょう。
    • good
    • 0
この回答へのお礼

ご回答有難うございます。
具体的な構文をご教示頂いて助かりました。

結果的に、4の方法だと
#1054 - Unknown column 'tableBname' in 'field list'
といったエラーが表示されたり、うまく接続?出来なかった感じなので、
3の方法を使用させていただきました。
最後に order by tableBid を付記することで、user_id順にうまく登録されました。

selectは()ダメなんですね、勉強不足で申し訳ございません。
values()のようにいけるのかと思い込んでいました・・・

ちょうど海外のサイトで同じエラーのスレッドがあったので、そこでunion allを見つけたのですが、詳しい使用方法を教えて頂いてありがとうございました!
おかげで様で無事INSERTすることが出来ました。

また4の方法も勉強して、次回うまくいけるようにしてみたいです。
ありがとうございました。

お礼日時:2014/05/05 12:25

Insert文のumeta_idを書くのをやめて、Select文にorder by user_idを追加

    • good
    • 0
この回答へのお礼

ありがとうございます。
order by user_id 、勉強になりました!

お礼日時:2014/05/05 12:19

Insert する列数とselect する列数は一致してないとダメでしょう。


Selectした列にエイリアスが無いから、列の並びと属性も一致してることが必要。

> from dbB.tableB where tableBname<> 'Admin'
from dbB.tableB where tableB.name<> 'Admin'
Where条件の左辺、正しい?Whereを除外して動作するなら
テーブル名の修飾、列名の存在等を確認。

この回答への補足

ご回答頂きましてありがとうございます。
エイリアスは省略してしまいましたが、付加しても無くても同じ結果でした。

補足となりますが、以下のSQL文だと問題なくINSERTされます。

insert into ***_usermeta (umeta_id,user_id,meta_key,meta_value)
select null,tableB.id,'first_name',''from dbB.tableB where tableB.name<> 'Admin'

これを以下のように複数行書けば恐らくINSERTできると思うのですが、

insert into ***_usermeta (umeta_id,user_id,meta_key,meta_value)
select null,tableB.id,'first_name',''from dbB.tableB where tableB.name<> 'Admin';

insert into ***_usermeta (umeta_id,user_id,meta_key,meta_value)
select null,tableB.id,'nickname',tableB.name from dbB.tableB where tableB.name<> 'Admin';

・・・

希望としては、一度のSQLで実行を行おうと思っており、
selectの後に()で括っているのですが、どうもそれの書き方?が間違っているのか
#1241 - Operand should contain 1 column(s) のエラーが表示されます。

meta_keyとmeta_valueの組み合わせが複数あり、
umeta_idはAUTO_INCREMENTなので、できればuser_idの順番どおり全てINSERTしたいと思っております。

umeta_id | user_id | meta_key | meta_value
1 | 1 | first_name|
2 | 1 | last_name |
3 | 1 | nickname | nicknameA
4 | 1 | ***_capabilities | a:1:{s:10:"subscriber";b:1;}
5 | 2 | first_name|
6 | 2 | last_name |
7 | 2 | nickname | nicknameB
8 | 2 | ***_capabilities | a:1:{s:10:"subscriber";b:1;}

・・・といった感じです。
実現が難しそうなら、select文を一行ずつ実行してみようかと考えています。

補足日時:2014/05/04 15:49
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!