简体   繁体   English

Visual FoxPro 9 C#OleDbAdapter插入-功能不可用

[英]Visual FoxPro 9 C# OleDbAdapter Insert - Feature is Not Available

How do I insert into a FoxPro table with a primary key whose default value is newid("tablename") using Microsoft's OLE DB Provider for Visual Foxpro 9.0 ? 如何使用Microsoft的Visual Foxpro 9.0 OLE DB提供程序将默认值为newid("tablename")的主键插入FoxPro表中?

I have two tables, one where the primary key has a default value of newid("tablename") , and the other whose data type is set to Integer (AutoInc) . 我有两个表,一个表的主键具有默认值newid("tablename") ,另一个表的数据类型设置为Integer (AutoInc)

When I try to run the same insert command on the newid table, I get the following OleDbException : 当我尝试在newid表上运行相同的insert命令时, newid以下OleDbException

Feature is not available

When I run insert on the table with Integer (AutoInc) as the primary key, it works. 当我使用Integer (AutoInc)作为主键在表上运行insert时,它可以工作。

Here is the code I am trying to execute: 这是我要执行的代码:

public void InsertData()
{
    using(var connectionHandler = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=\"C:\\path\\to\\db.dbc\";"))
    {
        var insertStatement = @"INSERT INTO mytable (mycol) values (?)";

        var insertCommand = new OleDbCommand(insertStatement, connectionHandler);

        insertCommand.Parameters.Add("mycol", OleDbType.Char).Value="blue";

        connectionHandler.Open();
        insertCommand.ExecuteNonQuery();
        connectionHandler.Close();
    }
}

Is there any reason OLE would not be able to execute an insert because of this newid() default value? 由于这个newid()默认值,OLE是否有任何原因无法执行insert


Another case that fixes my issue is if I manually specify an id in the insert clause. 解决我的问题的另一种情况是,如果我在insert子句中手动指定一个id ex: 例如:

var insertStatement = @"INSERT INTO mytable (id, mycol) values (?, ?)";
insertCommand.Parameters.Add("id", OleDbType.Integer).Value = 199;
insertCommand.Parameters.Add("mycol", OleDbType.Char).Value = "blue";

Additionally, I am able to run a select * from tablename on this table. 另外,我可以在此表上运行select * from tablename

select snippet: select代码段:

public DataTable GetData()
{
    var myData = new DataTable();

    using(var connectionHandler = new OleDbConnection("Provider=VFPOLEDB.1;Data Source=\"C:\\path\\to\\db.dbc\";"))
    {       
        var da = new OleDbDataAdapter();
        var mySQL = "select * from mytable";

        var myQuery = new OleDbCommand(mySQL, connectionHandler);
        connectionHandler.Open();

        da.SelectCommand = myQuery;

        da.Fill(myData);

        connectionHandler.Close();
    }

    return myData;
}

newid() SP: newid() SP:

function newId
parameter thisdbf
regional keynm, newkey, cOldSelect, lDone
keynm=padr(upper(thisdbf),50)
cOldSelect=alias()
lDone=.f.
do while not lDone
    select keyvalue from main!idkeys where keyname=keynm into array akey
    if _tally=0
        insert into main!idkeys (keyname) value (keynm)
        loop
    endif
    newkey=akey+1
    update main!idkeys set keyvalue=newkey where keyname=keynm and keyvalue=akey
    if _tally=1
        lDone=.t.
    endif
enddo
if not empty(cOldSelect)
    select &cOldSelect
else
    select 0
endif
return newkey

In a separate stored procedure, I have tried the following to isolate the key word regional : 在一个单独的存储过程中,我尝试了以下操作来隔离关键字regional

FUNCTION GetHello

regional hello

RETURN "HELLO WORLD"

Which seems to work (for example, setting the default value of a column to GetHello() then running an insert over OLEDB). 这似乎可行(例如,将列的默认值设置为GetHello()然后在OLEDB上运行插入)。

The following causes my stored procedure to fail with "Feature is not available" over OLEDB: 以下原因导致我的存储过程在OLEDB上失败,并显示“功能不可用”:

FUNCTION GetHello
LOCAL test
test="select * from customer"
&test
RETURN "hello"

Thanks for sharing the SP code! 感谢您共享SP代码! It shows what was the culprit. 它显示了罪魁祸首。

Though my nerves tend to do many corrections on that code I will only modify enough to make it work from both VFP and C#: 尽管我不愿意对该代码进行许多更正,但我只会对其进行足够的修改以使其在VFP和C#中都能正常工作:

function newId
parameter thisdbf
regional keynm, newkey, nOldSelect, lDone
keynm=padr(upper(thisdbf),50)
nOldSelect=select()
lDone=.f.
do while not lDone
    select keyvalue from main!idkeys where keyname=keynm into array akey
    if _tally=0
        insert into main!idkeys (keyname) value (keynm)
        loop
    endif
    newkey=akey+1
    update main!idkeys set keyvalue=newkey where keyname=keynm and keyvalue=akey
    if _tally=1
        lDone=.t.
    endif
enddo
Select (m.nOldSelect)
return newkey

The changed part is only related to that (if !empty(...)) block . 更改的部分仅与该块(if !empty(...)) block

The issue is this variable declaration line in the stored procedure: 问题是存储过程中的此变量声明行:

regional keynm, newkey, cOldSelect, lDone

The 'regional' keyword is a holdover from the old FoxPro 2.6 for DOS\\Windows. 'regional'关键字是旧版FoxPro 2.6 for DOS \\ Windows的保留。 It was only used in programs generated by the screen builder tool. 它仅在屏幕构建器工具生成的程序中使用。 It obviously still lurks within Visual FoxPro to support functionality that migrates old FoxPro 2.6 projects to Visual FoxPro, because the code works fine in VFP. 显然,它仍然潜伏在Visual FoxPro中,以支持将旧FoxPro 2.6项目迁移到Visual FoxPro的功能,因为代码在VFP中可以正常工作。 But the OLEDB driver doesn't support it. 但是OLEDB驱动程序不支持它。

Anyway, you need to change your stored procedure to use: 无论如何,您需要更改存储过程以使用:

local keynm, newkey, cOldSelect, lDone

... and recompile it, for which you will need Visual FoxPro. ...并重新编译它,为此您需要Visual FoxPro。 Ensure there are no OLEDB or other connections to it and then in the Visual FoxPro command window: 确保不存在任何OLEDB或其他连接,然后在Visual FoxPro命令窗口中:

compile c:\path\to\mydatabase.dbc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM