2013-06-26 61 views
5

我想創建一個屬性文件這樣的屬性文件...生成使用Shell腳本和結果從一個SQL查詢

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

......從這樣的查詢...

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

我該怎麼做?因爲我知道只有使用spool才能在這裏不起作用的CSV文件?

這些屬性文件將shell腳本來運行自動任務有所回升。我使用Oracle數據庫

+0

爲什麼不來構建構建文件在你的規格爲好,而不是依賴於純SQL一個新的shell腳本?另外,我認爲你需要指定你使用的是哪個數據庫,而不是一般的SQL標籤 –

+1

建議你的DBMS是什麼非常有用。 – RandomSeed

+1

感謝您的更新。注意我如何標記你的問題。您應該仔細標記問題,因爲大多數回答者只能通過標籤瀏覽問題。 – RandomSeed

回答

1

既然你mentionned spool我會假設你是運行在Oracle上。這應該會產生所需格式的結果,您可以馬上使用spool

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

同樣的方法應該是可以與所有的數據庫引擎,如果你知道一個litteral新線的正確咒語和字符串連接的語法。

1

有可能這個從你的命令行SQL客戶端,但作爲STTLCU指出它可能是更好地得到查詢輸出的東西「標準」(如CSV),然後用變換的結果一個shell腳本。否則,因爲您使用的許多功能不是任何SQL標準的一部分,所以它們將取決於數據庫服務器和客戶端應用程序。把這一步看做ETL的正面,在那裏你清理你「卸載」的數據,這樣它對於其他應用程序很有用。

確實有辦法將其構建到您的查詢應用程序中:例如,如果你使用類似perlDBI::Shell爲您的客戶端(它允許您使用DBI模塊連接到許多不同的服務器),你可以爵士樂您的輸出以不同的方式。但是,如果可以將查詢輸出發送到文本文件並通過awk運行,那麼在這裏你可能會最好。

話雖如此......這裏的PostgreSQL客戶端會怎麼做你想做的。請注意,設置格式的命令如何設置爲而不是 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=# 

隨着影響查詢的輸出psql客戶端\pset命令集的選項結果表。你大概可以找出哪個選項正在做什麼。如果你想用SQL客戶端來做到這一點,告訴我們它是哪一個,或者通過手冊頁閱讀,瞭解如何格式化你的查詢輸出。

2

也許像這樣?

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

輸出會是這樣:

id=1 
name=test1 

(有關選項的完整列表:man psql

1

我的答案是非常相似的已經發布了這個問題了兩下,但我嘗試解釋選項,並嘗試提供準確的答案。

使用Postgres的,你可以使用psql命令行實用程序,以獲得預期輸出

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

的選項有:

-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. 
1

您必須選擇是否要從shell或PL/SQL維護這樣的文件。這兩種解決方案都是可能的,都是正確的

因爲Oracle必須從文件中讀寫,所以我會從數據庫端進行操作。

您可以使用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; 

示例的源:http://psoug.org/snippet/Oracle-PL-SQL-UTL_FILE-file-write-to-file-example_538.htm

在您使用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') 
); 

在這一點上,你可以將數據寫入到你的表,該表具有與連接參數和值,即一列:「姓=喬恩

您可以通過甲骨文

才能閱讀由任何shell腳本閱讀它,因爲它是一個純文本。

然後,它只是一個查詢的事項,即:

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;