简体   繁体   English

使用Shell脚本生成属性文件和SQL查询的结果

[英]Generate a Properties File using Shell Script and Results from a SQL Query

I am trying to create a properties file like this... 我正在尝试创建这样的属性文件...

firstname=Jon
lastname=Snow
occupation=Nights_Watch
family=Stark

...from a query like this... ......来自这样的查询......

SELECT 
  a.fname as firstname, 
  a.lname as lastname, 
  b.occ as occupation... 
FROM 
  names a, 
  occupation b, 
  family c... 
WHERE... 

How can I do this? 我怎样才能做到这一点? As I am aware of only using spool to a CSV file which won't work here? 因为我知道只使用spool到CSV文件,这在这里不起作用?

These property files will be picked up by shell scripts to run automated tasks. shell脚本将拾取这些属性文件以运行自动化任务。 I am using Oracle DB 我正在使用Oracle DB

Perhaps something like this? 也许是这样的?

psql -c 'select id, name from test where id = 1' -x -t -A -F = dbname -U dbuser

Output would be like: 输出如下:

id=1
name=test1

(For the full list of options: man psql .) (有关选项的完整列表: man psql 。)

It is possible to to this from your command line SQL client but as STTLCU notes it might be better to get the query to output in something "standard" (like CSV) and then transform the results with a shell script. 可以从命令行SQL客户端进行此操作,但是如STTLCU所述,最好让查询以“标准”(如CSV)输出,然后使用shell脚本转换结果。 Otherwise, because a lot of the features you would use are not part of any SQL standard, they would depend on the database server and client application. 否则,因为您将使用的许多功能不是任何SQL标准的一部分,它们将依赖于数据库服务器和客户端应用程序。 Think of this step as sort of the obverse of ETL where you clean up the data you "unload" so that it is useful for some other application. 可以将此步骤视为ETL的正面,您可以清理“卸载”的数据,以便它对其他一些应用程序有用。

For sure there's ways to build this into your query application: eg if you use something like perl DBI::Shell as your client (which allows you to connect to many different servers using the DBI module) you can jazz up your output in various ways. 当然,有一些方法可以将它构建到您的查询应用程序中:例如,如果您使用perl DBI::Shell作为您的客户端(允许您使用DBI模块连接到许多不同的服务器),您可以通过各种方式使您的输出变得更好。 But here you'd probably be best off if could send the query output to a text file and run it through awk . 但是如果可以将查询输出发送到文本文件并通过awk运行它,那么你可能最好。

Having said that ... here's how the Postgresql client could do what you want. 话虽如此......这就是Postgresql客户端如何做你想做的事情。 Notice how the commands to set up the formatting are not SQL but specific to the client. 请注意,设置格式的命令不是 SQL,而是特定于客户端的命令。

~/% psql -h 192.168.2.69 -d cropdusting -u stubblejumper
psql (9.2.4, server 8.4.14)
    WARNING: psql version 9.2, server version 8.4.
         Some psql features might not work.
You are now connected to database "cropdusting" as user "stubblejumper".

cropdusting=# \pset border 0 \pset format unaligned \pset t \pset fieldsep =
Border style is 0.
Output format is unaligned.
Showing only tuples.
Field separator is "=".
cropdusting=# select year,wmean_yld from bckwht where year=1997 AND freq > 13 ;
1997=19.9761904762
1997=14.5533333333
1997=17.9942857143
cropdusting=# 

With the psql client the \\pset command sets options affecting the output of query results tables. 使用psql客户端, \\pset命令设置影响查询结果表输出的选项。 You can probably figure out which option is doing what. 你可以找出哪个选项正在做什么。 If you want to do this using your SQL client tell us which one it is or read through the manual page for tips on how to format the output of your queries. 如果您想使用SQL客户端执行此操作,请告诉我们它是哪一个或通过手册页阅读有关如何格式化查询输出的提示。

My answer is very similar to the two already posted for this question, but I try to explain the options, and try to provide a precise answer. 我的答案非常类似于已经发布的两个问题,但我尝试解释选项,并尝试提供一个精确的答案。

When using Postgres, you can use psql command-line utility to get the intended output 使用Postgres时,可以使用psql命令行实用程序来获取预期的输出

psql -F = -A -x -X <other options> -c 'select a.fname as firstname, a.lname as lastname from names as a ... ;'

The options are: 选项是:

-F : Use '=' sign as the field separator, instead of the default pipe '|'
-A : Do not align the output; so there is no space between the column header, separator and the column value.
-x : Use expanded output, so column headers are on left (instead of top) and row values are on right.
-X : Do not read $HOME/.psqlrc, as it may contain commands/options that can affect your output.
-c : The SQL command to execute
<other options> : Any other options, such as connection details, database name, etc.

Since you mentionned spool I will assume you are running on Oracle. 因为你提到了spool我会假设你在Oracle上运行。 This should produce a result in the desired format, that you can spool straight away. 这应该在所需的格式产生一个结果,你可以spool立竿见影。

SELECT
    'firstname=' || firstname || CHR(10) ||
    'lastname=' || lastname || CHR(10) -- and so on for all fields
FROM your_tables;

The same approach should be possible with all database engines, if you know the correct incantation for a litteral new line and the syntax for string concatenation. 如果您知道对于新行的正确咒语和字符串连接的语法,则所有数据库引擎都应该采用相同的方法。

You have to choose if you want to maintain such a file from shell or from PL/SQL. 您必须选择是否要从shell或PL / SQL维护此类文件。 Both solutions are possible and both are correct. 两种解决方案都是可能的,都是正确的。

Because Oracle has to read and write from the file I would do it from database side. 因为Oracle必须从文件中读取和写入,所以我会从数据库端进行读取和写入。

You can write data to file using UTL_FILE package. 您可以使用UTL_FILE包将数据写入文件。

DECLARE
    fileHandler UTL_FILE.FILE_TYPE;
BEGIN
    fileHandler := UTL_FILE.FOPEN('test_dir', 'test_file.txt', 'W');
    UTL_FILE.PUTF(fileHandler, 'firstname=Jon\n');
    UTL_FILE.PUTF(fileHandler, 'lastname=Snow\n');
    UTL_FILE.PUTF(fileHandler, 'occupation=Nights_Watch\n');
    UTL_FILE.PUTF(fileHandler, 'family=Stark\n');

    UTL_FILE.FCLOSE(fileHandler);
EXCEPTION
    WHEN utl_file.invalid_path THEN
        raise_application_error(-20000, 'ERROR: Invalid PATH FOR file.');
END;

Example's source: http://psoug.org/snippet/Oracle-PL-SQL-UTL_FILE-file-write-to-file-example_538.htm 示例来源: http//psoug.org/snippet/Oracle-PL-SQL-UTL_FILE-file-write-to-file-example_538.htm

At the same time you read from the file using Oracle external table. 同时使用Oracle外部表从文件中读取。

CREATE TABLE parameters_table
(
    parameters_coupled VARCHAR2(4000)
)
ORGANIZATION EXTERNAL
(
    TYPE ORACLE_LOADER
    DEFAULT DIRECTORY test_dir
    ACCESS PARAMETERS
    (
        RECORDS DELIMITED BY NEWLINE
        FIELDS
        (
            parameters_coupled VARCHAR2(4000)
        )
    )
    LOCATION ('test_file.txt')
);

At this point you can write data to your table which has one column with coupled parameter and value, ie: 'firstname=Jon' 此时,您可以将数据写入表中,该表具有一个具有耦合参数和值的列,即:'firstname = Jon'

You can read it by Oracle 您可以通过Oracle阅读它

You can read it by any shell script because it is a plain text. 您可以通过任何shell脚本读取它,因为它是纯文本。

Then it is just a matter of a query, ie: 然后它只是一个查询问题,即:

SELECT  MAX(CASE WHEN INSTR(parameters_coupled, 'firstname=')  = 1 THEN REPLACE(parameters_coupled, 'firstname=')  ELSE NULL END) AS firstname
,       MAX(CASE WHEN INSTR(parameters_coupled, 'lastname=')   = 1 THEN REPLACE(parameters_coupled, 'lastname=')   ELSE NULL END) AS lastname
,       MAX(CASE WHEN INSTR(parameters_coupled, 'occupation=') = 1 THEN REPLACE(parameters_coupled, 'occupation=') ELSE NULL END) AS occupation
FROM    parameters_table;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM