【问题标题】:Convert date format in the select statement在 select 语句中转换日期格式
【发布时间】:2014-09-26 01:00:22
【问题描述】:

我正在尝试将输出中的日期转换为dd-mm-yyyy 的格式。我曾尝试仅转换日期,但是只有当 select 语句显示输出时,我才能转换日期。

例如这是我的查询

select * 
from dbo.Car 
where 
    dbo.Car.[Date Registered] > DATEADD(year, -3, GetDate()) 
    and dbo.Car.rentalCost < 350 
ORDER by 
    [Date Registered] desc, brand asc;

我对上述语句的当前输出

在上面的查询中,我选择了所有内容,其中一列是DateRegistered,这是一个日期列,那么我该如何只转换日期列?我应该像这样在选择后指定每一列吗?

select 
   column1, column2, column3,
   Convert(varchar(10), CONVERT(date, Datecolumn4, 105), 103)...

有没有更简单的解决方案?

【问题讨论】:

  • 如果应用程序或报告软件可能有休假日期格式,请不要在查询中指定。

标签: sql-server tsql date type-conversion


【解决方案1】:

我创建了这个 SP,它动态创建一个列列表并将所有具有 Datetime 和 Date 数据类型的列转换为 dd-mm-yyyy。至少它有助于手动编写大量转换。

CREATE PROCEDURE usp_ColumnToStringDate(@p_TableName SYSNAME, @p_FilterString VARCHAR(4000) = NULL)
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @TableName SYSNAME
    DECLARE @ColumnName SYSNAME
    DECLARE @SchemaName SYSNAME
    DECLARE @DataType SYSNAME
    DECLARE @StartLoop INT
    DECLARE @EndLoop INT
    DECLARE @SQLColumnList VARCHAR(4000)
    DECLARE @SQL VARCHAR(4000)
    DECLARE @FilterString VARCHAR(4000)


    SET @TableName = @p_TableName
    SET @FilterString = @p_FilterString

    DECLARE @TargetTable TABLE (
                OrderID INT IDENTITY(1, 1),
                TableSchema SYSNAME,
                TableName SYSNAME,
                ColumnName SYSNAME,
                DataType SYSNAME
            )

    INSERT INTO @TargetTable
    SELECT   QUOTENAME(c.TABLE_SCHEMA),
             QUOTENAME(c.TABLE_NAME),
             QUOTENAME(c.COLUMN_NAME),
             UPPER(c.DATA_TYPE)
    FROM     INFORMATION_SCHEMA.COLUMNS c
    WHERE    c.TABLE_NAME = @TableName
    ORDER BY c.ORDINAL_POSITION

    --SELECT * FROM @TargetTable

    SELECT   @StartLoop = MIN(tt.OrderID),
             @EndLoop        = MAX(tt.OrderID),
             @SchemaName     = MIN(tt.TableSchema),
             @TableName      = MIN(tt.TableName)
    FROM     @TargetTable tt

    WHILE @StartLoop <= @EndLoop
    BEGIN
        SELECT   @DataType = tt.DataType,
                 @ColumnName = tt.ColumnName
        FROM     @TargetTable tt
        WHERE    tt.OrderID = @StartLoop

        --PRINT @ColumnName+' '+@DataType

        SET @SQLColumnList = ISNULL(@SQLColumnList, '')
            + CASE 
                   WHEN @DataType IN ('DATETIME', 'DATE') THEN CHAR(9) + CHAR(9)
                        + 'CONVERT(VARCHAR(10),' + @ColumnName + ', 105)'
                   ELSE CHAR(9) + CHAR(9) + @ColumnName
              END

        IF @StartLoop != @EndLoop
        BEGIN
            SET @SQLColumnList = @SQLColumnList + ',' + CHAR(13) + CHAR(10)
        END

        IF @StartLoop = 1
        BEGIN
            SET @SQLColumnList = 'SELECT' + REPLACE(@SQLColumnList, CHAR(9), ' ')
        END


        SET @StartLoop = @StartLoop + 1
    END
    SET @SQL = @SQLColumnList + CHAR(13) + CHAR(10) + 'FROM ' + @TableName + CHAR(13) + CHAR(10)
    SET @SQL = COALESCE(@SQL+@FilterString,@SQL)
    PRINT @SQL
END 

用法:

--SELECT Statement
EXEC usp_ColumnToStringDate 'ProductListPriceHistory',NULL

--SELECT Statement with Filter
EXEC usp_ColumnToStringDate 'ProductListPriceHistory','WHERE ProductID = ''1'''

--Use in other SP or assign to parameters
DECLARE @DSQL VARCHAR(MAX)

EXEC @DSQL =  usp_ColumnToStringDate 'ProductListPriceHistory','WHERE ProductID = ''1'''
PRINT REVERSE(SUBSTRING(REVERSE(@DSQL),2,LEN(@DSQL)))

【讨论】:

  • 谢谢,我需要一些时间才能理解这一点。
  • @JackyBoi,当然,但如果需要,请随时向我澄清。编码愉快。
【解决方案2】:

我认为最好在您的选择语句中指定每个列名并用于日期列:

select col1, col3, col3, CONVERT(varchar(10),[Date Registered], 105), col5, col6, col7
from dbo.Car 
where dbo.Car.[Date Registered] > DATEADD(year, -3, GetDate()) and  dbo.Car.rentalCost < 350 
ORDER by [Date Registered] desc, brand asc;

【讨论】:

  • 是的,几乎是我的第二个孩子,所以没有更简单的解决方案吗?我在想如果有几百个列怎么办?并且这些列是从其他查询动态更改的
  • 如果您只想基于另一个查询转换特定列,您可以查看动态 sql...
  • @JackyBoi,最简单的方法是让 App 团队处理,或者您可以编写动态 SQL 从 Information_Schema.Columns 中检索所有日期时间字段并编写一个案例来转换这些列。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-29
相关资源
最近更新 更多