为什么参数序列在SQL中很重要

时间:2013-05-15 01:49:45

标签: sql oracle

我认为这是入门级的,但我没有用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个参数。

2 个答案:

答案 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标记,则必须使用位置参数。

依此类推。