【问题标题】:Updating values in SQL Server database with MVC使用 MVC 更新 SQL Server 数据库中的值
【发布时间】:2012-04-28 04:55:53
【问题描述】:

我们对数据库中的日期有一个非常愚蠢的数据要求。月、日、年、分和小时存储在单独的列中。显然,这对于查询日期范围并不理想,尤其是使用实体框架。

我们决定只创建一个名为 combinedDate 的新列,它是一个带有相关日期信息的 SQL smalldatetime。在尝试更新我们的数据库时,我们的应用程序只是冻结并且从未完成更新。我们的测试数据库只有 8400 行,所以这绝对不是什么大问题。

我们应该为此使用存储过程吗?实现这一目标的最佳方法是什么?

对于数据库中的每个新条目,我们都必须对我们的日期数据执行此操作。这些条目可能一次出现 8400 行。

列格式:

  • Year int = 12
  • Month int = 4
  • Day int = 27
  • Hour int = 12
  • Min int = 0

新栏目:smalldatetime

  • combinedDate = '2012-04-27 12:00:00 PM'

【问题讨论】:

  • SQL = SQL Server ?? SQL 实际上只是 结构化查询语言 - 不是数据库产品...

标签: c# sql-server model-view-controller


【解决方案1】:

我同意计算列是最好的方法。

或许你应该考虑换个角度;而不是计算日期时间,而是通过

计算年/月/日/小时/分钟
Year as (DATEPART('yyyy', Time)) persisted not null,
Month as (DATEPART('m', Time)) persisted not null,
Day as (DATEPART('d', Time)) persisted not null,
Hour as (DATEPART('hh', Time)) persisted not null,
Min as (DATEPART('mi', Time)) persisted not null,
Time datetime not null

Link to DATEPART documentation

这样您将在更新时间列时自动验证其他字段。

免责声明:在撰写本文时,我不确定 DATEPART 是否可以确定使用持久化。

【讨论】:

  • 你的DATEPARTs 不完全正确 - 你应该有:Year as (DATEPART(YEAR, Time)) persisted not null - 第一个参数只是部分的定义,没有任何引号
【解决方案2】:

为什么不使用a computed column?这样您就可以确保您的年、月、日、小时、分钟和日期时间字段是同步的(如果您必须保留第一个)。

【讨论】:

  • 那么如何将这些 int 列转换为一个组合日期时间?
【解决方案3】:

正如其他人所提到的,创建计算列将是更好的选择。完全避免这种方法会更好。但是,如果无法避免这种方法,这里是您可以使用的计算列表达式。在输出部分您可以注意到,月份和分钟中的无效值实际上加起来以显示未来的正确日期

计算列表达式

(dateadd(year, (100) + [year],
    dateadd(month, [month] - (1),
        dateadd(day, [day] - (1),
            dateadd(hour, [hour],
                dateadd(minute, [min], (0))
                )
            )
        )
    )
)

示例脚本

CREATE TABLE dbo.myTable
(
        [year]  int NOT NULL
    ,   [month] int NOT NULL
    ,   [day]   int NOT NULL
    ,   [hour]  int NOT NULL
    ,   [min]   int NOT NULL
    ,   [smalldatetime]  AS (dateadd(year,(100)+[year],dateadd(month,[month]-(1),dateadd(day,[day]-(1),dateadd(hour,[hour],dateadd(minute,[min],(0))))))) PERSISTED
);

INSERT INTO dbo.myTable ([year], [month], [day], [hour], [min]) VALUES
    (12, 4, 27, 17, 34),
    (12, 6, 12, 4, 8),
    (11, 32, 12, 54, 87);

SELECT  [year]
    ,   [month]
    ,   [day]
    ,   [hour] 
    ,   [min] 
    ,   [smalldatetime] 
FROM    dbo.myTable;

样本输出

year month day hour min smalldatetime
---- ----- --- ---- --- -----------------------
12    4     27  17  34  2012-04-27 17:34:00.000
12    6    -12   4   8  2012-05-19 04:08:00.000
11    32    12  54  87  2013-08-14 07:27:00.000

【讨论】:

    【解决方案4】:

    与其尝试从C# 端进行更新,不如为combinedDate 指定一个computed column。看看DATETIMEFROMPARTS内置函数,可能有用

    编辑

    正如 cmets 中所指出的,DATETIMEFROMPARTS 仅在 SQL Server 2012 中可用,这是从 ymd(假设为整数)部分获取 DATETIME 的另一种方法:

    CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)
    

    【讨论】:

    • 不幸的是,这个非常有用的功能仅适用于 SQL Server 2012 - 之前的任何版本都没有......
    • 另一件事:YY-MM-DD 在 SQL Server 中创建 DATETIME 的格式不安全 - 例如它不适用于所有语言和日期格式设置。如果你想创建一个DATETIME,你需要使用YYYYMMDD没有任何破折号),或者然后YYYY-MM-DDTHH:MM:SS在所有配置下都可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多