创建SQL语句以根据特定月份创建列

时间:2014-07-07 14:14:14

标签: sql sql-server sql-server-2008 tsql

我试图创建一个允许我根据特定月份创建列的SQL代码,现在我有了这种语法,但是当我运行它时,它会显示错误。你能告诉我我做错了什么吗?

alter proc N50_Actualizar_PA
@fecha varchar(6)
as
begin

declare @fin int
declare @cont int
declare @query varchar(5000)
declare @query1 varchar(900)
declare @query2 varchar(900)
declare @query3 varchar(900)

set @fin = (SELECT day(dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,@fecha+'01')+1, 0))))
set @cont = 1
set @query3 = 'while '+@cont+' <= '+@fin+'
begin
set @query = ''S''+cast('+@cont+' as varchar(2))+'' float,E''+cast('+@cont+' as varchar(2))+'' float,''
exec (@query)
set '+@cont+' = '+@cont+' + 1
end'

set @query1 = 'if not exists (select * from sysobjects where name = ''PLANTA_REP_PA_'+@fecha+''')
begin
create table PLANTA_REP_PA_'+@fecha+'(
ITEM int,
UBIGEO varchar(255),
CENTRO_POBLADO varchar(255),
DISTRITO varchar(255),
PROVINCIA varchar(255),
DEPARTAMENTO varchar(255),
TELEFONO varchar(255),
TIPO varchar(255),
OBSERVACION varchar(255),
TECNOLOGIA varchar(255),
ID_VSAT_BTS varchar(255),
UBICACION_VSAT_BTS varchar(255),
NIVEL_SENAL varchar(255),
TIPO_ENERGIA varchar(255),
COMENTARIOS varchar(255),
CANT_LINEAS_B_ARRENDADOR varchar(255),
'+ @query3 +'
TOTAL_SALIENTE float,
TOTAL_ENTRANTE float,
SALIENTE_MOVILES float,
ENTRANTE_MOVILES float)
end
else
begin
truncate table PLANTA_REP_PA_' + @fecha + '
end'

set @query2 = 'INSERT INTO PLANTA_REP_PA_' + @fecha + '
Select * from Temp_Planta_Rep_PA'

exec (@query3)
print (@query1)
print (@query2)

end

1 个答案:

答案 0 :(得分:1)

一般问题#1:这是一个糟糕的问题。你在这里得到了很多赞成票,他们可能都是因为你的问题和目标没有明确规定,而且你没有提供足够的信息。但是,如果这还不够糟糕,那么发布&#34;修复我的代码&#34;问题是社会非常不满意的。 Read this在下次发布之前。{/ p>

一般问题#2:这是可怕的主意。您正在为特定的日期范围创建一个表格,您将盲目地截断...是的。不是一个好的设计。每个月的新表都是不好的做法,但那是你的事。

SQL问题#1:您正在尝试连接字符串和整数(set @query3 = 'while '+@cont+' <= '+@fin+' ...)。在执行此操作之前,您必须将这些整数转换为字符串。但这并不重要,因为

SQL问题#2:整个WHILE语句错误。我假设该语句的目的是用一个列的名称填充变量。但它并没有这样做。

SQL问题#2a - WHILE循环不会连接列列表。再读一遍:你告诉SQL执行@query,在最好的情况下它将是S1 float, E1 float,。那不是SQL命令。你需要做的是set @query = @query + 'S1 ...。这样,它将构建字符串。

SQL问题#2b - 变量的长度是错误的。尝试将varchar(5000)查询填充到varchar(900)查询中是不行的。

SQL问题#3:您永远不会将列列表附加到表定义中。而是通过写作

CANT_LINEAS_B_ARRENDADOR varchar(255),
'+ @query3 +'
TOTAL_SALIENTE float,

您告诉SQL将值设置为

CANT_LINEAS_B_ARRENDADOR varchar(255),
while 1 <= 28 
begin
set ...
TOTAL_SALIENTE float,

这永远不会奏效。你要做的是添加理论上位于@query中的连接字符串,在这种情况下你应该写

CANT_LINEAS_B_ARRENDADOR varchar(255),
'+ @query +'
TOTAL_SALIENTE float,

仍然无法解决问题,因为

SQL问题#4:您还没有执行@ query3。在尝试将这些值与表定义连接之前,必须构建和设置@query的值。相反,您需要执行WHILE循环并填充@query的值,然后再将其与@ query1连接。

您的方法和实践存在更多问题(例如在同一块中包含TRUNCATE TABLE命令)但我认为这给您提供了一般性的想法,坦率地说,我不是会员Stack Overflow,所以我可以帮你完成你的工作。我在这里是因为我喜欢SQL,想出一个谜题很有趣......而我在这里是因为有人花时间向我解释事情,如果我可以帮助那个人那么多。我向前付钱的方式。

我要发布下面的查询,这样可以让您更接近目标。这可能是一个坏主意,因为将它提供给您不会强迫您阅读我对您的代码的分析并自己进行更改。花时间比较两者,了解差异以及我为什么要做出这些改变,并从那里开始。机会是,它仍然需要调整,但在发布更多问题之前尝试自己修复它。如果您收到错误消息,请将其发送给Google。如果它运行但没有达到您的预期,请拉出打印的代码并通过它来找出原因。 Read this post关于询问&#34;修复我的代码&#34;的问题。祝你好运!

declare @fecha varchar(6)
set @fecha = '201402'

declare @fin int
declare @cont int
declare @query varchar(5000)
declare @query1 varchar(5000)
declare @query2 varchar(900)
declare @query3 varchar(900)

set @fin = (SELECT day(dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,@fecha+'01')+1, 0))))
print @fin


set @cont = 1
set @query = ''
while @cont <= @fin
  begin
    set @query = 
        @query + '
        S' + cast(@cont as varchar(2))+' float, 
        E' + cast(@cont as varchar(2))+' float, '
    set @cont = @cont+ 1
  end

SET @query1 = '
IF NOT EXISTS (select * from sysobjects where name = ''PLANTA_REP_PA_'+@fecha+''')
BEGIN
CREATE TABLE PLANTA_REP_PA_'+@fecha+'
  (
    ITEM int,
    UBIGEO varchar(255),
    CENTRO_POBLADO varchar(255),
    DISTRITO varchar(255),
    PROVINCIA varchar(255),
    DEPARTAMENTO varchar(255),
    TELEFONO varchar(255),
    TIPO varchar(255),
    OBSERVACION varchar(255),
    TECNOLOGIA varchar(255),
    ID_VSAT_BTS varchar(255),
    UBICACION_VSAT_BTS varchar(255),
    NIVEL_SENAL varchar(255),
    TIPO_ENERGIA varchar(255),
    COMENTARIOS varchar(255),
    CANT_LINEAS_B_ARRENDADOR varchar(255),
    '+ @query +'
    TOTAL_SALIENTE float,
    TOTAL_ENTRANTE float,
    SALIENTE_MOVILES float,
    ENTRANTE_MOVILES float
  )
END


TRUNCATE TABLE PLANTA_REP_PA_' + @fecha + '
end'

set @query2 = 'INSERT INTO PLANTA_REP_PA_' + @fecha + '
SELECT * FROM Temp_Planta_Rep_PA'

--exec (@query3)
print @query3
print (@query1)
print (@query2)