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

C# 获取表中列的第一个val的SQL是什么?,c#,sql,sql-server-ce,compact-framework,windows-ce,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 o

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

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-goldbergsque事件,我害怕触及到这一点;不过,这种小小的清理应该是可行的,不会让我的战利品发抖

更新 我想我是在SQL Server CE查询分析器结果中给出了答案——“从invHeader中选择前1个ID”:

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:
这似乎有点神秘,因为所有人都知道了,但有一件事我很想知道,SQLServerCE查询分析器“不好玩”

更新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 对不起,克塔克;谢谢你的帮助,但这实在是太麻烦了;最初的代码,虽然很有价值,但仍然有效;我还有更臭的鱼要炒,所以我要离开它,至少现在是这样。我试过这个:

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()中看到连接字符串后,我没有看到第二个连接字符串。

从invHeader中选择TOP 1 ID

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


ORDER BY
如果不希望返回任意记录。

避免使用数据集,请使用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。

不要使用数据集。永远

下面是一个很好的第一关。如果id字段通过TableDirect进行索引,则速度可能会更快,但我会先运行它,看看性能是否可以接受

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;
            }
        }
    }
}

ID是自动递增的吗?不-它们都是相同的值,令人敬畏。我震惊了。这听起来有点傻,但是您的查询分析器是否连接到了正确的数据库?这个命令应该在我所知道的任何SQL数据库中都能完成任务。@JohnBingham:欢迎来到我的世界-当你在处理早于剑齿虎的工具和技术时,你经常会感到震惊。我连接到了正确的数据库。SQL Compact不支持TOP。不要使用数据集-它们是深不可测的地狱生物。这是一个任意记录-显然它们在该列中都有相同的val。现有代码只取第一个,像陀螺一样旋转一段时间,然后退出。作为一名准社会主义者,我将以较少的分数将奖项授予猫。我的原始帖子:“顺便说一句,我知道这应该是一种标量调用,但在这些相互依赖的自主开发的方法中,发生了太多时髦的Rube-goldbergsque事件,我不敢碰它;这是一个.NET 1.1项目,它不支持隐式变量类型。我需要什么对象来替换这一行上的“var”:使用(var reader=command.ExecuteReader())?我当然更喜欢这段代码,但用这段代码替换现有方法会引发一个异常(但它本身就很模糊,抱怨我需要先安装一些文件,然后它才会不再害羞,并告诉我问题出在哪里).好像我还不知道-这是这个项目经常发生的事情-任何修复它的尝试都会导致另一个证据,证明它是完全无法治愈的。说到这个项目,我绝对赞成死刑(对于这个项目,也就是说,不是原始的编码者…)。知道它会抛出到哪里吗?显然,您必须输入一个有效的连接字符串。或者可以使用现有的
dbconn
变量来防止多个连接-这在旧版本的SQL CE上可能不受支持。我之所以喜欢此调用而不是标量或TOP调用,是因为它可以很容易地修改为使用TableDirect,如果您查询的表大小不限,性能提高了10倍。不过,我还是将您的表作为答案;如果我们重写此表,我将避免使用像酸败奶油利马豆这样的数据集。>不要使用数据集。永远不要使用。耶!
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;
            }
        }
    }
}