在表中的列中获取第一个val的SQL是什么?

时间:2013-09-19 21:47:47

标签: c# sql sql-server-ce compact-framework windows-ce

我想重构这段代码,因为它看起来很浪费,很古怪和奇怪:

public string getVersion()
{
    try
    {
        string dynSQL = "SELECT * FROM invHeader";
        DataSet workSites = dbconn.getDataSet(dynSQL);

        //Go thru dataset and display the working files
        //Only need one, although we'll be duplicating the version
        //per each site as a check value during upgrades
        //return workSites.Tables[0].Rows
        foreach (DataRow row in workSites.Tables[0].Rows)
        {
            sVersion = row["ID"].ToString();
            break;
        }
    }
    catch (Exception ex)
    {
        Duckbill.ExceptionHandler(ex, "InvHeader.getVersion");
    }

    return sVersion;
} // getVersion

我在想我可以将它改成这样的东西:

public string getVersion()
{
    try
    {
        string dynSQL = "SELECT FIRST ID FROM invHeader"; // I also tried "SELECT 1 ID FROM invHeader"
        DataSet workSites = dbconn.getDataSet(dynSQL);
        return workSites.Tables[0].Rows[0]["ID"].ToString();
    }
    catch (Exception ex)
    {
        Platypus.ExceptionHandler(ex, "InvHeader.getVersion");
    }
} // getVersion

...但是两个查询都没有返回我想要的内容(第一行中的ID值)。那么SQL是做什么的。

顺便说一句,我知道这个应该是某种标量调用,但是这些本土的,自我卷曲的方法中有很多时髦的Rube Goldbergesque事情发生在彼此依赖,我害怕触摸 ;但是,这个小小的清理应该是可行的,而不会在我的短靴中颤抖。

更新

我想我跳过了答案 - 在SQL Server CE查询分析器中“SELECT TOP 1 ID FROM invHeader”导致:

FAILED: SELECT TOP 1 ID FROM invHeader 
Error: x800...._E_ERRORSINCOMMAND
Native Error: (25501)
Description: There was an error parsing the query. [Token line number, Token line offset, Token in error,,]
Interface defining error: IID_ICommand
Paaram. 0:1
Param. 1: 8
Param. 2:0
Param. 3: TOP
Param. 4:
Param. 5:

这一切看起来都很神秘,但我做的一件事就是SQL Server CE查询分析器“没有被逗乐。”

更新2

我发现了一种更为恶劣的代码味道;这个方法的名称不仅会让你相信它会返回一个值(嗯,确实如此,这是真的);但是当它这样做时,它会从一个可能很大的表中获取所有记录,以便简单地抓住第一个(再次)。

写这篇文章的猫是否真的有可能没有得到关于“SELECT *”的挥霍使用的备忘录警告?

我可以在代码混淆竞赛中提交匿名条目吗?

public string getINVSite()
{
    string  siteStr   = "";
    string  dSQL      = "";
    DataSet workSites;

    dSQL      = "SELECT * FROM inventory";
    dbconn    = DBConnection.GetInstance();
    workSites = dbconn.getDataSet( dSQL );

#if true
//            DataRow row = workSites.Tables[0].Rows[0];

    siteStr = "1";
    if (workSites.Tables.Count > 0)
    {
        if(workSites.Tables[0].Rows.Count>0)
            siteStr = workSites.Tables[0].Rows[0]["ID"].ToString();
    }
    return( siteStr );
#else
    //Go thru dataset and display the working files
    foreach( DataRow row in workSites.Tables[0].Rows )
    {
        return( row["ID"].ToString() );
    }

    return( "" );
#endif
} // getINVSite

现在你知道我承受的负担;如果感到遗憾,请捐赠给您选择的慈善机构。

更新3

抱歉,ctacke;谢谢你的帮助,但这只是一个兔子洞太多了;原始代码,虽然Mad Hatter值得,但有效;我有更加臭鱼吃,所以我会离开它,至少现在。我试过这个:

public string getVersion()
{
    string conStr = "Data Source = " + dbconn.filename;
    MessageBox.Show(string.Format("conStr in InvHeader.getVersion() is {0}", conStr));//TODO: Remove after testing
    try
    {
        using (SqlCeConnection connection = new SqlCeConnection(conStr))
        {
            connection.Open();
            using (SqlCeCommand command = new SqlCeCommand("SELECT ID FROM invHeader", connection))
            using (SqlCeDataReader reader = command.ExecuteReader())
            {
                if (reader.Read())
                {
                    string s = reader.GetString(0);
                    MessageBox.Show(string.Format("version InvHeader.getVersion() is {0}", s));//TODO: Remove after testing
                    return s;// reader.GetString(0);
                }
                else
                {
                    // no result
                    return null;
                }
            }
        }
    }
    catch (Exception ex)
    {
        Pterodactyl.ExceptionHandler(ex, "InvHeader.getVersion");
        return string.Empty;
    }
}

......我仍然得到一个例外;在第一个MessageBox.Show()中看到连接字符串后,我没有看到第二个。

4 个答案:

答案 0 :(得分:4)

在MS SQL Server CE中,它是TOP (N)

SELECT TOP (1) ID 
FROM invHeader 
ORDER BY ???
如果您不想返回任意记录,请

ORDER BY

答案 1 :(得分:3)

不要使用DataSet。如初。

下面是一个很好的第一关。如果通过去TableDirect索引id字段可以使它更快,但是我先运行它来查看perf是否可以接受。

public string GetVersion()
{
    using (var connection = new SqlCeConnection("my connection string"))
    {
        connection.Open();
        using (var command = new SqlCeCommand("SELECT id FROM invHeader", connection))
        using (var reader = command.ExecuteReader())
        {
            if (reader.Read())
            {
                return reader.GetString(0);
            }
            else
            {
                // no result
                return null;
            }
        }
    }
}

答案 2 :(得分:2)

从invHeader中选择TOP 1 ID

答案 3 :(得分:2)

避免使用DataSet,请使用SqlCommand和ExecuteScalar方法。

<强>被修改

此代码应该是等效的,功能性的和更快的:

public string getVersion()
{
    try
    {
        // Use TOP (N) http://technet.microsoft.com/en-us/library/bb686896.aspx
        string dynSQL = "SELECT TOP (1) ID FROM invHeader";
        return (string)(new SqlCeCommand(dynSQL, dbconn.getConnection()).ExecuteScalar());
    }
    catch (Exception ex)
    {
        Platypus.ExceptionHandler(ex, "InvHeader.getVersion");
    }
} // getVersion   

假设dbconn是一个可以为您提供调用dbconn.getConnection()的SqlCeConnection的类。