2017-01-26 1 views
2

MatlabのPostgreSQLのリレーショナルデータをクエリするプロジェクトを行っています。私はMatlabとPostgreSQLを接続するためにこの例に従ってきました。PostgreSQLの列名を取得してMatlabの構造体データにインポートする方法

% Add jar file to classpath (ensure it is present in your current dir) 
javaclasspath('postgresql-9.0-801.jdbc4.jar'); 

% Username and password you chose when installing postgres 
props=java.util.Properties; 
props.setProperty('user', '<your_postgres_username>'); 
props.setProperty('password', '<your_postgres_password>'); 

% Create the database connection (port 5432 is the default postgres chooses 
% on installation) 
driver=org.postgresql.Driver; 
url = 'jdbc:postgresql://<yourhost>:<yourport>/<yourdb>'; 
conn=driver.connect(url, props); 

% A test query 
sql='select * from <table>'; % Gets all records 
ps=conn.prepareStatement(sql); 
rs=ps.executeQuery(); 

% Read the results into an array of result structs 
count=0; 
result=struct; 
while rs.next() 
    count=count+1; 
    result(count).var1=char(rs.getString(2)); 
    result(count).var2=char(rs.getString(3)); 
    ... 
end 

は私がするResultSetMetaData

rsmd = rs.getMetaData(); 
columnsNumber = rsmd.getColumnCount(); 
name1 = rsmd.getColumnName(1); 
name2 = rsmd.getColumnName(2); 

を使用してPgResultSetから列名を取得することができるが、私は、クエリの結果にそれを設定することができません

while rs.next() 
    count=count+1; 
    result(count).var1=char(rs.getString(2)); 
    result(count).var2=char(rs.getString(3)); 
    ... 
end 

ザ・var1とvar2は構造体データの結果の列の名前として表示され、変数name1とname2を代入すると、構造体結果の "var1"と "var2"の代わりに "name1"と "name2"代わりにf変数name1とname2に設定したPostgreSQLのカラム名。

ありがとうございました!

+1

:あなたは別の 構造で、各個別のタプルの結果を持っているしたい場合は、次のコードを使用することができますか?あなたは何を使っていますか? – Adriaan

+0

こんにちは、私はこれに2つのメインプラットフォームMatlabとPostgreSQLを使用しています。このコードはMatlabを接続するために使用され、PostgreSQLは主にJavaで書かれています。 – Trung

答えて

5

あなたのコードに関係することは、あなたが望むことを行うためにわずかに修正する必要があります。次のように修正されたコードは次のとおりです。

while rs.next() 
    count=count+1; 
    result(count).(name1)=char(rs.getString(2)); 
    result(count).(name2)=char(rs.getString(3)); 
    ... 
end 

問題がダイナミックなフィールド参照にあった、すなわち、あなたが文字列変数に入れて、その名前でいくつかのフィールドを参照する場合、これは表記.()によって行われます。動的フィールド参照の詳細については、Loren Shureのブログ「Loren on the Art of Matlab」の記事「動的フィールド参照の使用」を参照してください。

私が知る限り、PostgreSQLへのコネクタとしてJDBCを使用することは、かなり限られた量のスカラ型のデータをインポート/エクスポートする必要がある場合にのみ、ケース のために妥当であることに注意したい(スカラー数値、論理、文字列、タイムスタンプなど)。より複雑な型(配列など)に対処する必要がある場合やデータの量がかなり多い場合(約1Gb)、JDBCはもはや効率的ではありません。このような状況のために、あなたの問題(列名の取得とMatlab構造のデータのインポート)の両方を解決する、より効率的で便利な方法があります。つまり、これらの目的でPgMexを使用することができます。あなたのコードは、上記の(私たちは<>記号でマークされ、以下のすべてのパラメータが適切に満たされていると、対応するテーブルは、それぞれのデータベースに存在することを前提とし)、このような方法で変換することができます。

% Create the database connection 
dbConn=com.allied.pgmex.pgmexec('connect',[... 
    'host=<yourhost> dbname=<yourdb> port=<yourport> '... 
    'user=<your_postgres_username> password=<your_postgres_password>']); 

% A test query 
sql='select * from <table>'; % Gets all records 
pgResult=com.allied.pgmex.pgmexec('exec',dbConn,sql); % Perform this test query 

必要にカラム名を取得するにはあなたは次のように行う必要がある構造で、これらの結果を入れて、最後に

nFields=com.allied.pgmex.pgmexec('nFields',pgResult); 
fieldNameCVec=cell(nFields,1); 
for iField=1:nFields 
    fieldNameCVec{iField}=com.allied.pgmex.pgmexec('fName',pgResult,iField-1); 
end 

::次のコードを実行

% Read the results 
outCVec=cell(nFields,1); 
fieldSpecStr='%<field_type_1> %<field_type_2> ...'; 
inpCVec=num2cell(0:nFields-1); 
[outCVec{:}]=com.allied.pgmex.pgmexec('getf',pgResult,... 
    fieldSpecStr,inpCVec{:}); 
% Get only values ignoring NULLs (if NULLS are not to be ignored, the code 
% should be improved by taking into accout not only valueVec, but 
% also isNullVec and isValueNull being indicators of NULLs) 
fieldValCVec=cellfun(@(SFieldValInfo)SFieldValInfo.valueVec,... 
    outCVec,'UniformOutput',false); 
SResult=struct(transpose([fieldNameCVec(:) fieldValCVec(:)])); 

getffieldSpecStrを含む)コマンドの入力引数と出力引数の形式に関係しています.PgMexのWebサイトのドキュメントを参照してください。 すべてのタプルのフィールドの値は、 コマンドの1回の呼び出し(自分のコードで使用するサイクルではなく) で取得され、非常に高速に実行されることに注意してください(約3。 "Performance comparison of PostgreSQL connectors in Matlab" articleの末尾に記載されているように、直接JDBC接続を介してMatlab Database Toolbox を使用して実行したのと同じ操作ではなく、5倍 より速く実行できます。 これらの値を何らかの形で変換する必要はありません。すべてMatlabに優しくネイティブな方法(行列形式、 の多次元配列、構造体、その他のMatlab形式)で行われます。各特定のフィールドの

すべての値は、単に検索タプル の数と一致する第一の次元に沿ってサイズを有するアレイとして に上記のコードによってSResult構造の各フィールドに置かれます。これは、Java、C、MATLABとPostgreSQLをタグ付けされているのはなぜ

fieldValCVec=cellfun(@(valueVec)num2cell(valueVec,[2 ndims(valueVec)]),... 
    fieldValCVec,'UniformOutput',false); 
tupleFieldValCMat=transpose(horzcat(fieldValCVec{:})); 
SResultCVec=cellfun(@(tupleFieldValCVec)struct(... 
    transpose([fieldNameCVec(:) tupleFieldValCVec(:)])),... 
    num2cell(tupleFieldValCMat,1),'UniformOutput',false); 
SResultVec=vertcat(SResultCVec{:}); 
関連する問題