2

假设:

我需要从“ PrivateDB ”数据库中同步一个“ PublicDB ”。其中两个参数应该传递给存储过程,服务器名称和日期时间类型参数。

HistoryDate不是主键,而是用于更新。

设想:

如果今天是 8 日并且用户没有从 dateTimePicker -UI- 中选择任何以前的日期,则此存储过程只会在 8 日更新记录。

如果今天是 8 号并且用户在我的 SP 中选择 5th of month= targetdate,它应该从 4th 删除“PublicDB”表,然后再次插入 5th、6​​th 和 8th。

问题:服务器参数工作正常,但对于数据时间参数:

如果 Sp 在 sql server 中执行得到这个错误: 从字符串转换日期和/或时间时转换失败。

如果添加到表适配器,则会收到此错误: 从字符串转换日期/或时间时生成的 SELECT 语句对话失败。 *要将这些设置应用于您的查询,请单击完成*

这是sp:

CREATE PROCEDURE [dbo].[spname] @Server SYSNAME,

@TDate NVARCHAR(50) --have tested: DateTime

AS
BEGIN

    DECLARE @SQL1 NVARCHAR(2000);
    DECLARE @SQL2 NVARCHAR(2000);
    DECLARE @LastRecordDate DATETIME;
    DECLARE @Count INT;
    DECLARE @TargetDate DATETIME;

    SET @TargetDate = CONVERT(DATETIME, @TDate, 121);

    SET @Count = CONVERT(INT, 'SELECT COUNT(*) FROM   [' + @Server + '].[PublicDB].[dbo].[TableName]

        WHERE HistoryDate >= [' + @TargetDate + '] ');

    EXECUTE sp_executesql @Count;

    IF @Count > 0 BEGIN

        SET @SQL1 = 'DELETE FROM [' + @Server + '].[PublicDB].[dbo].[TableName] 

WHERE HistoryDate >= [' + @TargetDate + '] 

  INSERT INTO [PublicDB].[dbo].[TableName]
    SELECT  TOP 5
       [HistoryDate]
      ,[columnName1]
      ,[columnName2]
      ,[columnName3]
      ,[columnName4]
      ,[columnName5]
      ,[columnName6]
      FROM PrivateDB.dbo.TableName
      WHERE HistoryDate >= [' + @TargetDate + '] 
  ';

        EXECUTE sp_executesql @SQL1;

    END

    ELSE BEGIN

        SET @LastRecordDate = CONVERT(DATETIME, 'SELECT TOP 1 HistoryDate FROM [PublicDB].[dbo].[TableName] ORDER BY HistoryDate DESC', 121);

        -- has tested: cast('SELECT TOP 1 HistoryDate FROM [Public].[dbo].[TableName] ORDER BY HistoryDate DESC' as datetime)

        EXECUTE sp_executesql @LastRecordDate;

        SET @SQL2 = '

    INSERT INTO [' + @Server + '].[PublicDB].[dbo].[TableName]
      SELECT  TOP 5 
       [HistoryDate]
      ,[columnName1]
      ,[columnName2]
      ,[columnName3]
      ,[columnName4]
      ,[columnName5]
      ,[columnName6]
      FROM PrivateDB.dbo.TableName
      WHERE HistoryDate > [' + @LastRecordDate + ']

  ';

        EXECUTE sp_executesql @SQL2;

    END


END
4

1 回答 1

0

我认为这些行可能是问题所在

SET @Count = CONVERT(INT, 'SELECT COUNT(*) FROM   [' + @Server + '].[PublicDB].[dbo].[TableName]
             WHERE HistoryDate >= [' + @TargetDate + '] ');

您要求将字符串/日期时间转换为 int

我猜您正在尝试从 select 语句中获取计数,一种方法如下(未经测试!)

CREATE TABLE #t_count(no int) 
DECLARE @sqlcount varchar(1000)
DECLARE @count int
SET @sqlcount = 'INSERT into #t_count SELECT COUNT(*) 
            FROM   [' + @Server + '].[PublicDB].[dbo].[TableName]
            WHERE HistoryDate >=''' + convert(varchar(30),@TargetDate,120) + ''''
EXEC( @sqlcount )
SELECT @count = no FROM #t_count

示例sqlfiddle

编辑

我看到你更新了你的答案http://sqlfiddle.com/#!2/d41d8/14528

但是如果您阅读上面的答案,您会看到它

创建一个临时表

CREATE TABLE #t_count(no int) 

构建一个 sql 字符串以将计数插入到临时表中

SET @sqlcount = 'INSERT into #t_count SELECT COUNT(*) 
                FROM   [' + @Server + '].[PublicDB].[dbo].[TableName]
                WHERE HistoryDate >=''' + convert(varchar(30),@TargetDate,120) + ''''
EXEC( @sqlcount )

从表中获取计数值

SELECT @count = no FROM #t_count

您的编辑不会这样做!

此外,由于某种原因,您在 [] 中包含文字值,这些需要删除

好的

where historydate = '2012-12-12 12:12'

坏的

where historydate = [2012-12-12 12:12]
于 2013-06-11T08:52:11.060 回答