作为Barmar pointed-out:
每次在循环内回显时都会覆盖文件。
您可以通过在 CSV 的字段分隔符中包含空格来做到这一点。
有一些重要的警告:
- Shell 无法可靠地解析可能包含引号、转义引号的 CSV 字段。您应该考虑使用能够正确解析 CSV 并将值作为参数或
null 分隔字段(如 csvtool)返回的命令。
- 如果您的 SQL 数据库引擎知道
PREPARE 语句,那么使用PREPARE SQL UPDATE 请求并为其提供参数会更安全。您将在循环之前准备请求,然后提供参数并在循环中执行准备好的语句。
#!/usr/bin/env bash
while IFS=', ' read -r acctnum errcode date; do
cat <<SQL
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='$date' and ETL_ERR_CD='$errcode' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='$acctnum');
SQL
done < ignore.csv > sqlfile.txt
使用csvtool 解析exclude.csv 并将其转换为SQL 查询:
excludeCSV2sql:
#!/usr/bin/env bash
# This script uses csvtool to parse exclude.csv CSV data from stdin
# and output SQL queries to stdout
# Convert arguments from csvtool call, into an SQL query
to_sql ()
{
# Double single-quote for SQL string values if any
local -- \
acct_num="${1//\'/\'\'}" \
err_code="${2//\'/\'\'}" \
date="${3//\'/\'\'}"
cat <<SQL
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='$date' AND ETL_ERR_CD='$err_code' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='$acct_num'
);
SQL
}
# Export for use in csvtool call
export -f to_sql
# Process CSV from stdin
csvtool call to_sql -
测试:
使上述脚本可执行:
chmod +x excludeCSV2sql
创建示例test_exclude.csv:
cat >test_exclude.csv <<CSV
foo,bar,baz
here,it's using a single quote, string
this, "has a double-quoted string
with a newline", in it
10100000012, "R4242, has comma", 20200524
10100000042, R1337, 20200525
CSV
运行测试:
./excludeCSV2sql <test_exclude.csv >test.sql
检查结果:
test.sql
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='baz' AND ETL_ERR_CD='bar' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='foo'
);
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='string' AND ETL_ERR_CD='it''s using a single quote' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='here'
);
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='in it' AND ETL_ERR_CD='has a double-quoted string
with a newline' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='this'
);
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='20200524' AND ETL_ERR_CD='R4242, has comma' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='10100000012'
);
UPDATE ODS.PERF_ACCT_ERR_DTL SET REC_ACTV_IND='T'
WHERE BUS_DT='20200525' AND ETL_ERR_CD='R1337' AND ACCT_KEY
IN (
SELECT ACCT_KEY FROM ODS.ACCT_PORTFOLIO
WHERE ACCT_SRCH_NBR='10100000042'
);