2010-03-22 38 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();