繁体   English   中英

c#中来自oracle sql字符串值的名称变量

[英]name variable from oracle sql string value in c#

这是我在C#中的第一个项目。 我对Access VBA有一点经验。 我想将我的应用程序移到独立的程序中。 我正在查询具有训练类型和日期的表。 我想根据执行日期将某些类型的培训相互比较。 三种训练类型是RWT010,RWP000和RWT010BP。 如果RWT010BP存在且较新,则它是我唯一需要的。 否则,我需要RWT010和RWP000。 我已经弄清楚了如何将值加载到变量中,但是我需要能够使用它们。 我希望dateTime值的名称是同一行的trainType。 这样,我可以比较它们并输出正确的组合。

我以前的Access逻辑如下所示:

LABEL_DATE: IIf(IsNull([RWT010]),"RWT010BP: " & _
     Format([RWT010BP],"Short Date"),IIf([RWT010BP]>[RWT010],"RWT010BP: " & _
     Format([RWT010BP],"Short Date"),"RWT010: " & _
     Format([RWT010],"Short Date") & " & " & "RWP000: " & _
     Format([RWP000],"Short Date")))

这是我在C#中获得的成果:

Console.Write("Enter ID: ");
        int idnum = Convert.ToInt32(Console.ReadLine());
        string sql = "SELECT EXPID, TYPE, DATE_LATEST FROM TRAINING_TABLE where expid =" + idnum;



        OracleCommand cmd = new OracleCommand();

       cmd.Connection = conn;

        cmd.CommandText = sql;

        using (DbDataReader reader = cmd.ExecuteReader())
        {
            if (reader.HasRows)
            {

                while (reader.Read())
                {

                    int expid = reader.GetInt32(0);
                    string trainType = reader.GetString(1);
                    DateTime trainDate = reader.GetDateTime(2); 

看起来原始的Access逻辑具有一个带三个日期字段[RWT010][RWT010BP][RWP000]数据库行。 但是在Oracle中已被规范化,因此您将获得多行,每行都有一个名为[DATE_LATEST]日期时间字段,然后有一个名为[TYPE]名称字段,该字段等于"RWT010""RWT010BP""RWP000"

而且您在想,您想按名称处理那些RWP000 ,就像在Access中一样。 您说的没错,这是最清晰的方法,我将向您展示如何做。 我误会了你的要求。

一种实现方法是编写一个复制Access逻辑的Oracle存储过程。 这不是您提出的问题,但这是一种合法的方法。 但是,由于数据库的更改,它比Access版本要复杂得多,而且无论如何我多年都没有编写Oracle SQL,也没有Oracle服务器可以方便地给我有关分号的任意,隐式语法错误和空格。

因此,我要做的是在C#中编写一个循环,以从数据库行中获取日期时间并将其放入局部变量中,然后使用这些变量而不是字段在C#中复制Access逻辑。 与Access版本相比,它会有些冗长,但有时就是这样。

int idnum = Convert.ToInt32(Console.ReadLine());

string sql = "SELECT EXPID, TYPE, DATE_LATEST FROM TRAINING_TABLE where expid =" + idnum;

//  I don't know how you're using this so I'll just declare it here 
//  and leave that to you.
String dateLabel = "";

OracleCommand cmd = new OracleCommand();

cmd.Connection = conn;

cmd.CommandText = sql;

using (DbDataReader reader = cmd.ExecuteReader())
{
    DateTime? RWT010 = null;
    DateTime? RWT010BP = null;
    DateTime? RWP000 = null;

    //  No need to check reader.HasRows. If it has no rows, reader.Read()
    //  will return false the first time, that's all. 

    while (reader.Read())
    {
        //  Doesn't look to me like expid is used
        //int expid = reader.GetInt32(0);
        string trainType = reader.GetString(1);
        DateTime trainDate = reader.GetDateTime(2);

        switch (trainType) {
            case "RWT010":
                RWT010 = trainDate;
                break;
            case "RWT010BP":
                RWT010BP = trainDate;
                break;
            case "RWP000":
                RWP000 = trainDate;
                break;
        }
    }

    if (RWT010 == null || RWT010BP > RWT010) {
        dateLabel = String.Format("RWT010BP: {0:d}", RWT010BP);
    } else {
        dateLabel = String.Format("RWT010: {0:d} & RWP000: {1:d}", RWT010, RWP000); 
    }
}

原始逻辑是这样的:

  If RWT010 isn't null, 
      Do A
  Otherwise, if RWT010BP > RWT010
      ALSO do A
  But if none of the above, 
      Do B

前两个分支执行完全相同的操作,因此我们可以将它们都压缩为一个分支。

正如他们所说,“不要重复自己”。 您不想一年以后再返回此代码,想知道这两行是否必须相同,然后猜测错误,否则就不会注意到它们是相同的,而只更改其中之一。 只是一团糟。

如果您不熟悉String.Format() ,那就很多了。 在第一个参数字符串中, {0}表示“在此处插入第二个参数”; {1}表示“插入第三个”,依此类推。 花括号内的“:d”是可选的; 这意味着将“ d”作为格式信息传递给其插入的值。 DateTime会将“ d”解释为“ Short Date”。 您也可以这样:

dateLabel = String.Format("RWT010BP: {0}", RWT010BP.Value.ToShortDateString());

或像这样:

dateLabel = "RWT010BP: " + RWT010BP.Value.ToShortDateString();

我必须使用RWT010BP.Value在该行,而不只是RWT010BP因为RWT010BP与申报? 之后。 这使其成为“可为空”的值。 常规的DateTime不能为null,但是我们需要在此处容纳null。

如果您使用的是C#6,则可以这样做,我更喜欢。 我上面没有使用它,因为我不知道您使用的是哪个版本的C#。 始终希望尽量减少代码的混乱程度。

dateLabel = $"RWT010BP: {RWT010BP:d}";

与上面的String.Format("{0:d}", ...) “:d”相同。

还有一件事: idnum是一个int,但永远不要将字符串值连接到SQL字符串中。 这是一个巨大的安全漏洞,并且这里的人们(正确地,我怕)会给您一个非常艰难的时期,甚至无法考虑它。

如此答案所示,使用OracleCommand.Parameters代替。 即使在这种情况下,我个人也会将其用作条件反射。

暂无
暂无

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

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