用于在 ASP.Net 中更新或插入资产的 SQL CE 语句

本文关键字:SQL 语句 CE 插入 ASP Net 更新 用于 | 更新日期: 2023-09-27 18:31:59

我正在创建一个Web表单以将信息插入数据库。我进行此设置以插入键入的信息没有问题,但是如果数据库中已存在该条目,则尝试将命令重新格式化为UPDATE信息时遇到了麻烦。

尝试提交更改时出现以下错误:

解析查询时出错。[ 令牌行号 = 1,令牌行偏移量 = 7,令牌错误 = 资产 ]

说明:执行当前 Web 请求期间发生未经处理的异常。请查看堆栈跟踪,了解有关错误及其在代码中起源位置的详细信息。

异常详细信息:System.Data.SqlServerCe.SqlCeException:解析查询时出错。[ 令牌行号 = 1,令牌行偏移量 = 7,令牌错误 = 资产 ]

源错误:

第 39 行:插入(资产编号、序列号、资产类型、型号、位置、修改日期、注释), 第 40 行:值(@0、@1、@2、@3、@4、@5、@6)"; 第 41 行:数据库。执行(insertCommand, assetNumber, serialNumber, assetType, model, toCube, currentTime, comments); 第 42 行:Response.Redirect("~/AssetLookup"); 第 43 行:}

代码在第 41 行出错。我在下面的代码中唯一更改的是 SQL 语句,所以我确定这有问题。这是我第一次尝试使用 SQL;我做了一些挖掘,试图找出该语句的问题,但特别是我在使用时遇到了问题......部分。我真的不确定应该去那里什么,我觉得这可能是问题所在。

var assetNumber = "";
var serialNumber = "";
var assetType = "";
var model = "";
var toCube = "";
var comments = "";
if(IsPost && Validation.IsValid()){
    assetNumber = Request.Form["assetNumber"];
    serialNumber = Request.Form["serialNumber"];
    assetType = Request.Form["assetType"];
    model = Request.Form["model"];
    toCube = Request.Form["toCube"];
    var currentTime = DateTime.Now;
    comments = Request.Form["comments"];
    var db = Database.Open("Assets");
    var insertCommand = 
    @"MERGE Assets AS Target 
      USING (SELECT assetNumber, serialNumber FROM Assets) AS Source
      ON (Target.assetNumber = Source.assetNumber AND Target.serialNumber = Source.serialNumber)
        WHEN MATCHED THEN 
            UPDATE SET
                AssetNumber=@0,
                SerialNumber=@1,
                AssetType=@2,
                Model=@3,
                Location=@4,
                DateModified=@5,
                Comments=@6                                      
        WHEN NOT MATCHED THEN 
            INSERT (AssetNumber, SerialNumber, AssetType, Model, Location, DateModified, Comments), 
            VALUES (@0, @1, @2, @3, @4, @5, @6)";
    db.Execute(insertCommand, assetNumber, serialNumber, assetType, model, toCube, currentTime, comments);
    Response.Redirect("~/AssetLookup");
}

就像我说的,我确定我的 SQL 语句在某处搞砸了,因为我"有点"理解它,但对使用特别困惑......部分。所有表列和变量名称都根据代码/db 的其余部分正确设置。有人可以就我应该用于此命令的语法提供一些建议吗?

更新:

根据史蒂夫的评论,我更新了问题,以反映这是SQL CE而不是标准版本。

用于在 ASP.Net 中更新或插入资产的 SQL CE 语句

看起来您没有任何将目标与来源联系起来的东西。您正在使用 ON 子句有效地将目标表与自身进行比较。

也许尝试这样的事情:

var assetNumber = "";
var serialNumber = "";
var assetType = "";
var model = "";
var toCube = "";
var comments = "";
if(IsPost && Validation.IsValid()){
    assetNumber = Request.Form["assetNumber"];
    serialNumber = Request.Form["serialNumber"];
    assetType = Request.Form["assetType"];
    model = Request.Form["model"];
    toCube = Request.Form["toCube"];
    var currentTime = DateTime.Now;
    comments = Request.Form["comments"];
    var db = Database.Open("Assets");
    var insertCommand = 
    @"MERGE Assets AS Target 
      USING (SELECT @0 as assetNumber, @1 as serialNumber) AS Source
      ON (Target.assetNumber = Source.assetNumber AND Target.serialNumber = Source.serialNumber)
        WHEN MATCHED THEN 
            UPDATE SET
                AssetNumber=@0,
                SerialNumber=@1,
                AssetType=@2,
                Model=@3,
                Location=@4,
                DateModified=@5,
                Comments=@6                                      
        WHEN NOT MATCHED THEN 
            INSERT (AssetNumber, SerialNumber, AssetType, Model, Location, DateModified, Comments), 
            VALUES (@0, @1, @2, @3, @4, @5, @6)";
    db.Execute(insertCommand, assetNumber, serialNumber, assetType, model, toCube, currentTime, comments);
    Response.Redirect("~/AssetLookup");
}

我不是 100% 的,因为我不太精通 Razor 或通过代码运行查询(我通常坚持存储的过程),但听起来您想将传入的资产和序列号与表中的实际内容进行比较,而您以前拥有的不会这样做。

以一种非常基本的方式,我通过将一些 C# if/else 逻辑(因为 SQL CE 也不支持)与基本的 SQL 语句混合来解决这个问题。

此代码检查表单提交中的资产和序列号是否匹配,并在找到匹配项时进行更新。如果未返回任何记录,则会将资产添加到数据库中:

var db = Database.Open("Assets");
var query = "SELECT * FROM Assets WHERE AssetNumber = @0 AND SerialNumber = @1";
var record = db.QuerySingle(query, assetNumber, serialNumber);
if (record != null) {
    var updateCommand = 
    @"UPDATE Assets SET
        AssetNumber=@0,
        SerialNumber=@1,
        AssetType=@2,
        Model=@3,
        Location=@4,
        DateModified=@5,
        Comments=@6                                      
    WHERE AssetNumber=@0 AND SerialNumber=@1";
    db.Execute(updateCommand, assetNumber, serialNumber, assetType, model, toCube, currentTime, comments);
} else {
    var insertCommand = 
    @"INSERT INTO Assets (AssetNumber, SerialNumber, AssetType, Model, Location, DateModified, Comments) 
    VALUES (@0, @1, @2, @3, @4, @5, @6)";
    db.Execute(insertCommand, assetNumber, serialNumber, assetType, model, toCube, currentTime, comments);
}

此代码嵌套在上一个代码块中列出的 if(IsPost...) 方法中,并替换前面存在的 SQL 语句。它仍然需要一些工作来实施额外的检查,但基本逻辑完全符合我想要它做的事情。

感谢@Steve为我指出正确的方向!