我认为这是入门级的,但我没有用Google搜索任何答案..
构建查询时,我们是否必须使用绝对序列中的:1,:2 ...东西?从我的测试来看,似乎是的。但是不调用stmt-> setXXX(n,val)只是用val设置语句中的第n个参数?它是如何实现的?
请参阅下面的示例:
if (bNewContent) //new
{
sql = "BEGIN PackProductManagement.procAddOTTContent(:1, :2, :3, :4, :5, :6, :7); END; ";
}
else //update
{
sql = "UPDATE OTT_Content SET ContentID = :1, ContentType = :2, FingerPrint = :3, IsHighLevelSafe = :4, ";
sql += "OutProtection = :5, OfflinePlayback = :6, ModifyTime = sysdate ";
sql += "WHERE ContentID = :1";
}
try
{
OpenStatement(sql);
stmt->setString(1, ac->ContentDesc.ContentID);
stmt->setUInt(2, ac->ContentDesc.ContentType);
stmt->setUInt(3, ac->ContentDesc.FingerPrint);
stmt->setUInt(4, ac->ContentDesc.HighLevelSafe);
stmt->setUInt(5, ac->ContentDesc.OutputProtection);
stmt->setUInt(6, ac->ContentDesc.OfflinePlayback);
if (bNewContent)
{
stmt->setUInt(7, 0); //only used if new
}
stmt->execute();
CloseStatement(true);
}
在此示例中,bNewContent
始终为FALSE,因此我们始终运行update语句。以上查询工作正常。但是,如果我更改下面的更新查询(在更新语句的开头删除了ContentID = :1,
),我将得到一个ORA-01722 INVALID_NUMBER。我为什么不能这样做:2:3:4:5:6:1?如果setXXX像队列一样实现,为什么以上:1:2:3:4:5:6:1工作??
sql = "UPDATE OTT_Content SET ContentType = :2, FingerPrint = :3, IsHighLevelSafe = :4, ";
sql += "OutProtection = :5, OfflinePlayback = :6, ModifyTime = sysdate ";
sql += "WHERE ContentID = :1";
提前致谢!
编辑:
以下测试结果:(基于ZZa的回答)
sql = "UPDATE OTT_Content SET ContentID = :x ContentType = :x, FingerPrint = :x, IsHighLevelSafe = :x, ";
sql += "OutProtection = :x, OfflinePlayback = :x, ModifyTime = sysdate ";
sql += "WHERE ContentID = :x";
以上代码不适用于6个参数。
sql = "UPDATE OTT_Content SET ContentID = :1 ContentType = :x, FingerPrint = :x, IsHighLevelSafe = :x, ";
sql += "OutProtection = :x, OfflinePlayback = :x, ModifyTime = sysdate ";
sql += "WHERE ContentID = :1";
以上代码适用于6个参数。
答案 0 :(得分:4)
根据ORACLE documentation绑定变量按照它们的放置顺序使用,但不是如何命名。这就是你得到例外的原因。因此,您只需按参考顺序设置参数(在您删除第一个的情况下,首先提到的是ContentType
),并且它们的命名方式无关紧要。
您的代码看起来像这样,它仍然可以正常工作:
if (bNewContent) //new
{
sql = "BEGIN PackProductManagement.procAddOTTContent(:x, :x, :x, :x, :x, :x, :x); END; ";
}
else //update
{
sql = "UPDATE OTT_Content SET ContentID = :x, ContentType = :x, FingerPrint = :x, IsHighLevelSafe = :x, ";
sql += "OutProtection = :x, OfflinePlayback = :x, ModifyTime = sysdate ";
sql += "WHERE ContentID = :x";
}
try
{
OpenStatement(sql);
stmt->setString(1, ac->ContentDesc.ContentID);
stmt->setUInt(2, ac->ContentDesc.ContentType);
stmt->setUInt(3, ac->ContentDesc.FingerPrint);
stmt->setUInt(4, ac->ContentDesc.HighLevelSafe);
stmt->setUInt(5, ac->ContentDesc.OutputProtection);
stmt->setUInt(6, ac->ContentDesc.OfflinePlayback);
if (bNewContent)
{
stmt->setUInt(7, 0); //only used if new
}
stmt->execute();
CloseStatement(true);
}
答案 1 :(得分:2)
答案是,这取决于。
如果您使用.net和odbc,则必须使用位置参数。如果您使用的是.net和sql server,则可以使用命名参数。如果在ColdFusion中使用cfstoredproc标记,则必须使用位置参数。
依此类推。