2010-03-22 46 views
3

可以從MATLAB調用.NET,所以我想我會嘗試使用ADO.NET連接到數據庫。從MATLAB調用ADO.NET

我似乎碰到了一個阻塞問題 - 無論何時嘗試創建一個Command對象,它都會引發錯誤。

你可以試試這個自己:

>> NET.addAssembly('System.Data'); 
>> sqlconn = System.Data.SqlClient.SqlConnection(); 
>> sqlconn.State 

ans = 

    Closed  

>> % So far, so good 
>> sqlcmd = System.Data.SqlClient.SqlCommand(); 
??? Error using ==> System.Data.SqlClient.SqlCommand 
'Connection' is already defined as a property. 

>> 

有誰有一些洞察到這一點?這看起來像是MATLAB的一個純粹而簡單的錯誤 - 也許碰巧每個.NET類都有一個名爲「Connection」的屬性。

我是否應該放棄使用MATLAB與.NET交談的數據庫?


答(感謝對法齊爾的調查):升級MATLAB的版本比2009年a更大。

+0

我從來沒有用過MATLAB。它可以調用本地wcf服務嗎?如果是這樣,讓它爲你做db工作? – 2010-03-22 07:00:07

+0

MATLAB提供了許多選項來引入用不同語言編寫的組件。但是,我正在嘗試短期最簡單的解決方案。 – 2010-03-22 21:37:09

回答

2

我無法在MATLAB中重現該問題。您正在使用哪個版本的MATLAB?

>> version 

ans = 

7.9.1.705 (R2009b) Service Pack 1 

>> NET.addAssembly('System.Data'); 
sqlconn = System.Data.SqlClient.SqlConnection(); 
sqlconn.State 
sqlcmd = System.Data.SqlClient.SqlCommand() 

ans = 

    Closed  


sqlcmd = 

    System.Data.SqlClient.SqlCommand handle 
    Package: System.Data.SqlClient 

    Properties: 
       Connection: [] 
    NotificationAutoEnlist: 1 
       Notification: [] 
       Transaction: [] 
       CommandText: [1x1 System.String] 
      CommandTimeout: 30 
       CommandType: [1x1 System.Data.CommandType] 
     DesignTimeVisible: 1 
       Parameters: [1x1 System.Data.SqlClient.SqlParameterCollection] 
      UpdatedRowSource: [1x1 System.Data.UpdateRowSource] 
         Site: [] 
       Container: [] 

    Methods, Events, Superclasses 

>> 
+0

我升級到R2010a(從R2009a)。現在它可以工作。 – 2010-03-26 05:56:20

3
NET.addAssembly('System.Data'); 
sqlconn = System.Data.SqlClient.SqlConnection(); 
sqlcmd = sqlconn.CreateCommand(); 
sqlcmd.CommandText = "SELECT count(id) FROM sometable"; 
sqlconn.Open(); 
sqlrdr = sqlcmd.ExecuteReader(); 
sqlrdr.Read(); 
sqlrdr.GetInt64(0) 
+0

Thanks,CreateCommand有效。但是現在如果我設置了CommandText屬性,MATLAB會告訴我,在我逐步完成代碼的情況下,屬性不存在。在我不通過代碼的情況下整個環境崩潰。 – 2010-03-22 08:18:55

3

我應該認輸,放棄使用MATLAB交談使用.NET數據庫?

不,但是要意識到你也可以使用MATLAB的Java語言,如果你熟悉JDBC,這很簡單。

我不得不寫一個快速的輔助函數,因爲的Class.forName()似乎不尊重MATLAB的javaclasspath,不得不串用CHAR()顯式轉換,但除此之外,它工作得很好:

// MatlabDBAdapter.java 

import java.sql.*; 

public class MatlabDBAdapter { 

    public void loadDriver(String driverClass) throws ClassNotFoundException 
    { 
     Class.forName(driverClass); 
    } 
    public Connection getConnection(String dburl) throws SQLException 
    { 
     return DriverManager.getConnection(dburl); 
    } 
} 

示例m文件:

% dbexample.m 
% adapted from "getting started" section 
% of http://www.zentus.com/sqlitejdbc/ 

% replace the following two lines with 
% 1. where you put the compiled MatlabDBAdapter, 
% 2. also where you put the driver jar file 


javaaddpath('c:/appl/java/project/MatlabDBAdapter/bin'); 
javaaddpath('c:/appl/java/common/sqlitejdbc-v056.jar'); 

dba=com.example.test.database.MatlabDBAdapter(); 
dba.loadDriver('org.sqlite.JDBC'); 
conn=dba.getConnection('jdbc:sqlite:test.db'); 

disp ('Adding data....'); 

stat = conn.createStatement(); 
stat.executeUpdate('drop table if exists people;'); 
stat.executeUpdate('create table people (name, occupation);'); 
prep = conn.prepareStatement(... 
    'insert into people values (?, ?);'); 

prep.setString(1, 'Gandhi'); 
prep.setString(2, 'politics'); 
prep.addBatch(); 
prep.setString(1, 'Turing'); 
prep.setString(2, 'computers'); 
prep.addBatch(); 
prep.setString(1, 'Wittgenstein'); 
prep.setString(2, 'smartypants'); 
prep.addBatch(); 

conn.setAutoCommit(false); 
prep.executeBatch(); 
conn.setAutoCommit(true); 

disp ('Reading back data....'); 

rs = stat.executeQuery('select * from people;'); 
while (rs.next()) 
    % need to explicitly convert java.lang.String using char() 
    disp(['name = ' char(rs.getString('name'))]); 
    disp(['job = ' char(rs.getString('occupation'))]); 
end 
rs.close(); 
conn.close();