2017-02-28 1 views
1

Ich versuche, das Ergebnis einer Abfrage zu nehmen und das Ergebnis als eine Variable für den Namen einer Datei festzulegen. Ich habe Beiträge gelesen und festgestellt, dass Lesen von einer Auswahl und dann eine Variable aus dem Ergebnis verursacht Problem aber ich nicht folgen, wie ich es umgehen kann.Shell-Variable aus SELECT-Anweisung in Informix setzen?

Wenn ich eine direkte Abfrage ausführen ....

echo "SET isolation dirty read; Select * from site;" | dbaccess davedb 

erhalte ich die folgende Antwort, die erwartet wird.

Ich habe verschiedene Varianten der unten mit DECLARE, INTO oder AS versucht, aber nichts funktioniert. Das Folgende ist das Wesentliche dessen, was ich erreichen möchte.

#!/bin/bash 
dateFormat=`date +'%Y%m%d'` 

dbaccess davedb <<! 2>/dev/null 
set isolation dirty read; 

SELECT site_name AS $NAME 
FROM site; 
! 

touch "/export/home/dave/"$NAME"_"$dateFormat.txt 
+0

Willkommen bei Stack Overflow. Bitte beachten Sie, dass die bevorzugte Art zu sagen "Danke" hier ist durch Up-Voting gute Fragen und hilfreiche Antworten (sobald Sie genug Ruf zu tun haben), und durch die Annahme der hilfreichsten Antwort auf alle Fragen Sie fragen (Das gibt Ihnen auch einen kleinen Schub für Ihre Ruf). Bitte lesen Sie die [Über] Seite und auch [Wie stelle ich Fragen? hier?] (Http://stackoverflow.com/help/how-to-ask) und [Was mache ich, wenn jemand meine Frage beantwortet ?] (http://stackoverflow.com/help/someone-answers) –

Antwort

1

Es gibt verschiedene Möglichkeiten, dies zu beantworten.

Ich bin sehr versucht zu sagen "und deshalb schrieb ich SQLCMD zwanzig (oh, Kummer; nein, es ist dreißig jetzt - 1986!) Vor dreißig Jahren". DB-Access ist sehr nützlich für alle möglichen Zwecke, aber diese Art von Shell-Skripten ist nicht ihre Stärke, und SQLCMD wurde geschrieben, um diesen Mangel zu decken.

NAME=$(sqlcmd -d davedb -e 'set isolation to dirty read' \ 
       -e 'select site_name from site') 

Unter der Annahme, dass habhaft SQLCMD (beachten Sie, dies ist nicht das Microsoft johnny-come-lately Programm mit dem gleichen Namen) ist keine Option, dann werden Sie prüfen wollen, wie DB-Zugang zu zwicken in die Vorlage. Es tut sein Möglichstes, um zurückzuschlagen!

Vorausgesetzt, dass Sie den Namen in einem Shell-Variable aufnehmen mögen, können Sie vielleicht verwenden:

cat <<'EOF' | 
SET ISOLATION TO DIRTY READ; 
OUTPUT TO "/dev/stdout" WITHOUT HEADINGS SELECT site_name FROM site; 
EOF 
dbaccess davedb - 2>/dev/null | 
tr -d ' \n' 

Wenn Sie dies von der Befehlszeile ausführen, sehen Sie die Site-Namen, unmittelbar gefolgt von Ihrer prompten (Da alle Zeilenumbrüche - 5 von ihnen - durch den Befehl tr entfernt wurden), spielt das keine Rolle, wenn Sie die Ausgabe in einer Variablen erfassen.

Die OUTPUT-Anweisung ist in DB-Access (nicht der Datenbankserver) integriert. Es schreibt das Ergebnis einer SELECT-Anweisung in die benannte Datei. Ich nannte "/dev/stdout", was auf den meisten modernen Unix-ähnlichen Systemen dasselbe ist wie die Standardausgabe des Prozesses. Das Qualifikationsmerkmal WITHOUT HEADINGS lässt die Angabe der Spaltennamen aus der Ausgabe aus. Dies reduziert die Menge an Müll, die von dem Programm emittiert wird. Wenn Sie nicht /dev/stdout haben, können Sie stattdessen einen temporären Dateinamen angeben und dann die Datei lesen - aber das ist ein Ärgernis.

Es gibt eine Reihe von Varianten, wie SQL an DB-Access übergeben werden kann. Sie könnten die cat vermeiden, indem Sie echo verwenden (aber es gibt immer noch eine Pipeline dort), oder indem Sie eine Bash here string direkt an DB-Access oder eine here document als Standardeingabe für DB-Access verwenden oder eine somefile.sql erstellen, die SQL und dann enthält somefile.sql (oder auch nur somefile) als Dateinamen anstelle des - Argument übergeben.

Montage dieses in Ihrem Skript, erhalten Sie auf mit einer Variante bis:

dateFormat=$(date +'%Y%m%d') 
NAME=$(cat <<'EOF' | 
SET ISOLATION TO DIRTY READ; 
OUTPUT TO "/dev/stdout" WITHOUT HEADINGS SELECT site_name FROM site; 
EOF 
dbaccess davedb - 2>/dev/null | 
tr -d ' \n') 

if [ -n "$NAME" ] 
then touch "/export/home/dave/${NAME}_${dateFormat}.txt" 
fi 

Der Code wurde mit SELECT SITENAME FROM Systables WHERE tabid = 1 getestet, weil SITENAME eine eingebaute Funktion auf Informix ist, die den Servernamen zurückgibt (und auch ein lokal verfügbarer Datenbankname - die allgegenwärtige stores Datenbank. Es ist nicht klar, ob Ihre Site Tabelle und site_name Spalte diesen Wert oder etwas anderes speichert; in den meisten Punkten ist es egal.

+0

Vielen Dank für die Erklärung und das Skriptformular funktioniert perfekt. Danke noch einmal. – cw2