我使用Freemarker模板引擎生成一个插入Postgres的语句,其中包含来自csv文件的数据。数据库中有一个日期类型的列(' birthdate' ),如果该值不存在,插入应包含NULL(以安抚Postgres)或实际的生日,如果提供。像这样的东西:
INSERT INTO web_iws.broker (id,create_timestamp,update_timestamp,sfid,deleted,account_name,first_name,last_name,title,ssn,phone,mobile_phone,fax,email,mailing_street,mailing_city,mailing_state,mailing_postal_code,mailing_country,broker_number,npn,ga,ga_number,birthdate,appointed,indor_corp) VALUES(nextval('web_iws.broker_id_seq'::regclass),now(),now(),'003i00234597gnNAAQ',FALSE,'001i045681aYEiMAAW','Mason','Demarcove','Broker','','','','','mrdemarcove@abc.com','','','','','','BRN7J0943','','Savoy Associates','NJGA0306',NULL,'Appointed','');
INSERT INTO web_iws.broker (id,create_timestamp,update_timestamp,sfid,deleted,account_name,first_name,last_name,title,ssn,phone,mobile_phone,fax,email,mailing_street,mailing_city,mailing_state,mailing_postal_code,mailing_country,broker_number,npn,ga,ga_number,birthdate,appointed,indor_corp) VALUES(nextval('web_iws.broker_id_seq'::regclass),now(),now(),'003i07852RjON3sRN',FALSE,'001i0002'43567AAV','Maritza','Galsh','','145-98-1794','','','','marytza@galshben.com','718 River Road','Red Bank','NJ','07701','','BRNJ0877','7420702','Walsh Benefits','NJGA0008','1939-12-03','Appointed','Indv');
Freemarker中有更优雅的东西来表达上述要求:
"<#if birthdate?has_content>'${birthdate}',<#else>NULL,</#if>"
也许内置的日期能够用可配置的默认值或某种三元表达式替换空值,以便删除if ... ...
提前谢谢。
我尝试了@ddekany发布的建议,这是我看到的:
具有空生日值的随机原始数据记录(在csv中)( NJGA0001,指定之间的空格)如下所示:
2015-07-28T19:59:09.000Z,2015-07-28T19:59:15.000Z,003i000002oQSRMAA4,FALSE,Centerpoint Consulting,Briant,Hlonan,,,(973) 522-7886,,,briant@centerpointbenefits.com,,,,,,BRNJ0780,,BenefitMall,NJGA0001,,Appointed,Individual
试用时:
"${birthdate?has_content?then(\"'${birthdate}'\", 'NULL')}"+
在我的Java模板中,我收到了错误消息:
11:52:37.168 [main] DEBUG util.BrokerInsertGeneratorTest - Error during saml template buildingfreemarker.core.ParseException: Error on line 1, column 672, in template insertProducingTemplate
Found then, expecting one of: chunk, is_date, last, root, j_string, contains, is_hash, long, float, ends_with, namespace, matches, time, values, seq_last_index_of, uncap_first, byte, substring, is_transform, web_safe, groups, seq_contains, is_macro, index_of, word_list, int, is_method, eval, parent, xml, number, capitalize, if_exists, rtf, node_type, double, is_directive, url, size, default, is_boolean, split, node_name, is_enumerable, seq_index_of, is_sequence, sort, is_node, sort_by, left_pad, cap_first, interpret, children, node_namespace, chop_linebreak, date, short, last_index_of, is_collection, ancestors, length, trim, datetime, is_string, reverse, c, keys, upper_case, js_string, has_content, right_pad, replace, is_hash_ex, new, is_number, is_indexable, lower_case, string, exists, html, first, starts_with
使用此表达式:
"${(\"'${birthdate}',\")!'NULL'}"+
产生以下内容:
INSERT INTO web_iws.broker (id,create_timestamp,update_timestamp,sfid,deleted,account_name,first_name,last_name,title,ssn,phone,mobile_phone,fax,email,mailing_street,mailing_city,mailing_state,mailing_postal_code,mailing_country,broker_number,npn,ga,ga_number,birthdate,appointed,indor_corp) VALUES(nextval('web_iws.broker_id_seq'::regclass),now(),now(),'003i000002oQSRMAA4',FALSE,'Centerpoint Consulting','Briant','Hlonan','','','(973) 522-7886','','','briant@centerpointbenefits.com','','','','','','BRNJ0780','','BenefitMall','NJGA0001','','Appointed','Individual');
哪个更好,因为它会创建&#39; NJGA0001&#39;&#39;&#39;&#39;&#39;&#39;指定&#39; ,但不会成为Postgres接受 - 对于空日期字段,它需要NULL。
我愿意听取其他建议。
这里是Java模板字符串,它在处理if语句时需要较少的详细程度:
public final static String templateStr = "INSERT INTO web_iws.broker (id,create_timestamp,update_timestamp,"
+ "sfid,deleted,account_name,first_name,last_name,title,ssn,phone,mobile_phone,fax,email,mailing_street,mailing_city,mailing_state,mailing_postal_code,mailing_country,broker_number,npn,ga,ga_number,birthdate,appointed,indor_corp) "+
"VALUES(nextval('web_iws.broker_id_seq'::regclass),now(),now(),"+
"'${sfid}',"+
"${deleted},"+
"'${account_name}',"+
"'${first_name}',"+
"'${last_name}',"+
"'${title}',"+
"'${ssn}',"+
"'${phone}',"+
"'${mobile_phone}',"+
"'${fax}',"+
"'${email}',"+
"'${mailing_street}',"+
"'${mailing_city}',"+
"'${mailing_state}',"+
"'${mailing_postal_code}',"+
"'${mailing_country}',"+
"'${broker_number}',"+
"'${npn}',"+
"'${ga}',"+
"'${ga_number}',"+
"<#if birthdate?has_content>'${birthdate}',<#else>NULL,</#if>"+
"'${appointed}',"+
"'${indor_corp}');";
答案 0 :(得分:0)
您可以使用postgres'to_char
功能。例如:
<#if birthdate?has_content>to_char('${birthdate}', 'YYYY-MM-DD'),<#else>NULL,</#if>
http://www.postgresql.org/docs/current/static/functions-formatting.html
答案 1 :(得分:0)
没有三元运算符,但有一个等价的内置函数:
${birthdate?has_content?then("'${birthdate}'", 'NULL')}
还有一个专门的运算符来为缺失值提供默认值,例如someValue!defaultValue
。你的情况有点棘手,因为你需要添加这些引号,所以它会像:
${("'${birthdate}'")!'NULL'}
此外,请注意!
运算符不会将空字符串视为缺失,与?has_content
不同。
最后,如果你做了很多,可能值得为它定义一个#function
。