【问题标题】:how to pass variable from shell script to sqlplus如何将变量从shell脚本传递给sqlplus
【发布时间】:2013-07-08 15:49:05
【问题描述】:

我有一个调用 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 脚本以传递变量名吗?

即:模型 =“建筑” 并将其传递给 file.sql?

有类似的吗?

【问题讨论】:

  • 你的 shell 脚本看起来有点乱了; load_triples.sh 是脚本,sqlplus 调用就在 @/opt/... 行之前?
  • 查看此答案:stackoverflow.com/questions/2236201/…。您可以将参数添加到 SQL 命令行并使用 &1 类型的符号进行引用。

标签: sql oracle shell sqlplus


【解决方案1】:

您似乎有一个包含单个 SQL*Plus 命令的 heredoc,尽管它看起来不像 cmets 中指出的那样正确。您可以在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 中引用位置参数using substitution variables:

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

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


您可以传递多个值,并按顺序引用它们,就像在 shell 脚本中使用位置参数一样 - 第一个传递的参数是 &amp;1,第二个是 &amp;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));

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

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

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

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

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

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

【讨论】:

  • 有没有办法让别名(在我的情况下为 'total_count')具有与传递的字符串名称相关联的名称?即'SELECT COUNT(*) as $1 ...'
  • @Angelina - 我已经用一个使用位置替换变量命名的别名的示例更新了答案。我希望这就是你的意思。
  • 定义有效;定义 MY_ALIAS = &1 定义 MY_MODEL = &2 SELECT COUNT(*) as &MY_ALIAS FROM TABLE(SEM_MATCH( THANK YOU @Alex Poole
猜你喜欢
  • 2020-12-06
  • 2013-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 1970-01-01
相关资源
最近更新 更多