我有这个代码用于创建查询和执行sql-procedure但我捕获了缺失异常
public String generateQuery(Integer idAccount, Long[] phoneList, Date date){
StringBuilder query=new StringBuilder();
query.append("declare arr_pn owa_util.vc_arr;\n");
query.append("begin\n");
int idx = 1;
for (Long p : phoneList)
{ query.append("arr_pn(" + idx + "):='" + String.valueOf(p) + "';\n"); idx++; }
query.append("call LOC_MAINCLIENT.set_client_relations(");
query.append("id_account_ => " + idAccount);
query.append(", phone_number_list_ => arr_pn");
query.append(", dt_ => " + date);
query.append("); end;");
return String.valueOf(query);
}
之后我得到了这个查询
declare arr_pn owa_util.vc_arr;
begin
arr_pn(1):='12345';
arr_pn(2):='678970';
arr_pn(3):='5675675';
call LOC_MAINCLIENT.set_client_relations(id_account_ => 123, phone_number_list_ => arr_pn, dt_ => Sun Mar 24 21:54:00 NOVT 2013); end;
我做错了什么?
答案 0 :(得分:1)
目前没有引用日期字符串,所以无论如何它都是有效的,但是解析器会将冒号解释为绑定变量标记;特别是它将寻找绑定变量:54和:00。
快速回答是将日期字符串放入引号。但是该日期格式不太可能与您的数据库(会话)期望的格式相匹配,因此您需要将日期格式化为可以使用的字符串,并提供格式以避免歧义。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
query.append(", dt_ => to_date('" + sdf.format(date)
+ "', 'YYYY-MM-DD HH24:MI:SS')");
你也不需要call
,所以摆脱它。这会产生这样的字符串(添加换行符和缩进以使其更容易看到):
declare
arr_pn owa_util.vc_arr;
begin
arr_pn(1):='12345';
arr_pn(2):='678970';
arr_pn(3):='5675675';
LOC_MAINCLIENT.set_client_relations(id_account_ => 123,
phone_number_list_ => arr_pn,
dt_ => to_date('2013-03-24 21:54:00', 'YYYY-MM-DD HH24:MI:SS'));
end;
假设您的包程序声明为:
procedure set_client_relations(id_account_ number,
phone_number_list_ owa_util.vc_arr, dt_ date);
......这应该运行。当然,它是否符合您的实际需求是另一回事。
如果数据库与您的区域设置不匹配,您可能还需要对时区执行某些操作。
执行此操作的正确方法是使用预准备语句,将所有值作为绑定变量提供,并传递正确的数据类型 - 将日期作为日期而不是字符串表示形式传递。这对阵列来说有点复杂,但肯定能够做到。您已经说过这是遗留代码,您必须使用它,但您仍应调查切换到绑定变量。