how to pass variable from shell script to sqlplus

前端 未结 1 1229
挽巷
挽巷 2020-12-29 17:56

I have a shell script that calls file.sql

I am looking for a way to pass some parameters to my file.sql.

If I don\'t pass a variable with some value to the s

相关标签:
1条回答
  • 2020-12-29 18:17

    You appear to have a heredoc containing a single SQL*Plus command, though it doesn't look right as noted in the comments. You can either pass a value in the heredoc:

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

    or if BUILDING is $2 in your script:

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

    If your file.sql had an exit at the end then it would be even simpler as you wouldn't need the heredoc:

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

    In your SQL you can then refer to the position parameters using substitution variables:

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

    The &1 will be replaced with the first value passed to the SQL script, BUILDING; because that is a string it still needs to be enclosed in quotes. You might want to set verify off to stop if showing you the substitutions in the output.


    You can pass multiple values, and refer to them sequentially just as you would positional parameters in a shell script - the first passed parameter is &1, the second is &2, etc. You can use substitution variables anywhere in the SQL script, so they can be used as column aliases with no problem - you just have to be careful adding an extra parameter that you either add it to the end of the list (which makes the numbering out of order in the script, potentially) or adjust everything to match:

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

    or:

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

    If total_count is being passed to your shell script then just use its positional parameter, $4 or whatever. And your SQL would then be:

    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));
    

    If you pass a lot of values you may find it clearer to use the positional parameters to define named parameters, so any ordering issues are all dealt with at the start of the script, where they are easier to maintain:

    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));
    

    From your separate question, maybe you just wanted:

    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));
    

    ... so the alias will be the same value you're querying on (the value in $2, or BUILDING in the original part of the answer). You can refer to a substitution variable as many times as you want.

    That might not be easy to use if you're running it multiple times, as it will appear as a header above the count value in each bit of output. Maybe this would be more parsable later:

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

    If you set pages 0 and set heading off, your repeated calls might appear in a neat list. You might also need to set tab off and possibly use rpad('&1', 20) or similar to make that column always the same width. Or get the results as CSV with:

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

    Depends what you're using the results for...

    0 讨论(0)
提交回复
热议问题