5

我有一个调用 file.sql 的 shell 脚本

我正在寻找一种将一些参数传递给我的 file.sql 的方法。

如果我没有将具有某些值的变量传递给 sql 脚本,我将不得不使用 SELECT 语句创建多个 .sql 文件,而这一切都会改变。

我的 shell 脚本调用 file.sql:

sqlplus -S user/pass@localhost
echo " Processing triples"
./load_triples.sh BUILDING/Mapping_File BUILDING Y >> load_semantic.log

@/opt/D2RQ/file.sql
exit;
EOF

这就是我的 file.sql 的样子:

SET ECHO ON;
SPOOL count.log

SELECT COUNT(*) as total_count
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('BUILDING'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

SPOOL OFF;

我可以修改我的 shell 脚本以便它传递变量名吗?

即:model =“BUILDING”并将其传递给file.sql?

有这样的吗?

4

1 回答 1

15

您似乎有一个heredoc包含单个 SQL*Plus 命令,尽管它看起来不像注释中指出的那样正确。您可以在 中传递一个值heredoc

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql BUILDING
exit;
EOF

或者如果BUILDING$2您的脚本中:

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql $2
exit;
EOF

如果你最后file.sql有一个exit,那么它会更简单,因为你不需要heredoc

sqlplus -S user/pass@localhost @/opt/D2RQ/file.sql $2

然后,在您的 SQL 中,您可以使用替换变量来引用位置参数:

...
}',SEM_Models('&1'),NULL,
...

&1替换为传递给 SQL 脚本的第一个值,BUILDING; 因为那是一个字符串,它仍然需要用引号引起来。如果在输出中显示替换,您可能想要set verify off停止。


您可以传递多个值,并按顺序引用它们,就像在 shell 脚本中的位置参数一样 - 第一个传递的参数是&1,第二个是&2等等。您可以在 SQL 脚本中的任何地方使用替换变量,因此可以使用它们作为没有问题的列别名 - 您只需要小心添加一个额外的参数,您可以将其添加到列表的末尾(这可能会使脚本中的编号无序)或调整所有内容以匹配:

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql total_count BUILDING
exit;
EOF

或者:

sqlplus -S user/pass@localhost << EOF
@/opt/D2RQ/file.sql total_count $2
exit;
EOF

如果total_count被传递给你的 shell 脚本,那么只需使用它的位置参数,$4或者其他什么。然后您的 SQL 将是:

SELECT COUNT(*) as &1
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&2'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

如果您传递了很多值,您可能会发现使用位置参数来定义命名参数更清晰,因此任何排序问题都在脚本开头处理,它们更易于维护:

define MY_ALIAS = &1
define MY_MODEL = &2

SELECT COUNT(*) as &MY_ALIAS
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&MY_MODEL'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

从您的单独问题中,也许您只是想要:

SELECT COUNT(*) as &1
FROM TABLE(SEM_MATCH(
'{
        ?s rdf:type :ProcessSpec .
        ?s ?p ?o
}',SEM_Models('&1'),NULL,
SEM_ALIASES(SEM_ALIAS('','http://VISION/DataSource/SEMANTIC_CACHE#')),NULL));

...所以别名将与您查询的值相同(中的值$2,或BUILDING答案的原始部分中的值)。您可以根据需要多次引用替换变量。

如果您多次运行它,这可能不容易使用,因为它会在输出的每一位中显示为计数值上方的标题。也许这稍后会更容易解析:

select '&1' as QUERIED_VALUE, COUNT(*) as TOTAL_COUNT

如果您set pages 0set heading off,您的重复呼叫可能会出现在一个整洁的列表中。您可能还需要set tab off并且可能使用rpad('&1', 20)或类似方法使该列始终具有相同的宽度。或者通过以下方式获取 CSV 格式的结果:

select '&1' ||','|| COUNT(*)

取决于您将结果用于什么...

于 2013-07-10T16:06:16.060 回答