【发布时间】:2015-03-10 12:45:36
【问题描述】:
我有一个存储过程,如果表存在则删除它,然后它重新创建表并用相关数据填充它,我的一个朋友有大约相同的代码,唯一真正的区别在于列标题桌子。
作为一个插图,这是我的样子(不是真的,只是一个表示)。
+----+-----+-----+--------+
| ID | Foo | Bar | Number |
+----+-----+-----+--------+
| 1 | x | x | 0 |
| 2 | x | x | 1 |
+----+-----+-----+--------+
这就是他的样子
+----+--------+--------+-----+--------+
| ID | BarFoo | FooBar | Num | Suffix |
+----+--------+--------+-----+--------+
| 1 | x | x | 0 | a |
| 2 | x | x | 1 | b |
+----+--------+--------+-----+--------+
同样,这些只是情况的代表。
由于这是一项学校作业,老师将创建并执行两个 SP,但是在使用另一个 SP 后创建 SP 时,我收到此错误:
消息 207,级别 16,状态 1,程序 XYZ,第 59 行
列名“Foo”无效。消息 213,级别 16,状态 1,程序 XYZ,第 61 行
列名或提供的值的数量与表定义不匹配。
然而,在这两个存储过程的开始,我们有这样的:
CREATE PROCEDURE XYZ
AS
BEGIN
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'TABLENAME'
AND xtype = 'u')
DROP TABLE TABLENAME;
据我了解,这应该删除整个表格?包括表/列定义和数据?
到目前为止,我发现的唯一解决方法是在创建存储过程之前单独执行DROP TABLE,这对我们不起作用,因为它确实必须在存储过程中。
非常感谢您的帮助:)
编辑:这是我的实际代码,除了 cmets,这正是它在我的脚本中的样子(不包括它后面的其他代码)。
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'BerekenStatistiek'
AND xtype = 'p')
DROP PROCEDURE BerekenStatistiek;
GO
CREATE PROCEDURE BerekenStatistiek
@jaar INT=0
AS
BEGIN
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'Statistiek'
AND xtype = 'u')
DROP TABLE Statistiek;
DECLARE @year AS NVARCHAR (4);
SET @year = CONVERT (NVARCHAR (4), @jaar);
SELECT *,
CAST (Kost - Korting + Freight AS MONEY) AS Netto,
'' AS Richting
INTO Statistiek
FROM (SELECT O.Kwartaal,
CAST (SUM(O.Kost) AS MONEY) AS Kost,
CAST (SUM(O.Korting) AS MONEY) AS Korting,
CAST (SUM(O.Freight) AS MONEY) AS Freight
FROM (SELECT CASE
WHEN CONVERT (NVARCHAR (8), OrderDate, 112) BETWEEN @year + '0101' AND @year + '0331' THEN 1
WHEN CONVERT (NVARCHAR (8), OrderDate, 112) BETWEEN @year + '0401' AND @year + '0630' THEN 2
WHEN CONVERT (NVARCHAR (8), OrderDate, 112) BETWEEN @year + '0701' AND @year + '0930' THEN 3
WHEN CONVERT (NVARCHAR (8), OrderDate, 112) BETWEEN @year + '1001' AND @year + '1231' THEN 4
END AS 'Kwartaal',
ROUND(UnitPrice * Quantity, 2) AS Kost,
Round((UnitPrice * Quantity) * Discount, 2) AS Korting,
Freight
FROM Orders AS O
INNER JOIN
OrderDetails AS Od
ON O.OrderID = Od.OrderID
WHERE CONVERT (NVARCHAR (4), OrderDate, 112) = @year) AS O
GROUP BY O.Kwartaal) AS O1;
ALTER TABLE Statistiek ALTER COLUMN Kwartaal INT NOT NULL;
ALTER TABLE Statistiek ALTER COLUMN Richting NVARCHAR (8);
ALTER TABLE Statistiek
ADD PRIMARY KEY (Kwartaal);
...
这是他的代码(在变量中插入值只是为了便于阅读(他的代码有点笨重):
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'BerekenStatistiek'
AND xtype = 'p')
BEGIN
DROP PROCEDURE BerekenStatistiek;
END
GO
CREATE PROCEDURE BerekenStatistiek
@jaartal INT
AS
BEGIN
DECLARE @huidigkwartaal AS INT = 1;
DECLARE @beginmaand AS INT;
DECLARE @eindmaand AS INT;
DECLARE @vorige_netto_ontvangsten AS MONEY;
IF EXISTS (SELECT *
FROM sysobjects
WHERE name = 'Statistiek'
AND xtype = 'U')
BEGIN
DROP TABLE Statistiek;
END
CREATE TABLE Statistiek
(
kwartaalnummer INT ,
beginmaand INT ,
eindmaand INT ,
orderbedrag MONEY ,
korting MONEY ,
vervoerskost MONEY ,
netto_ontvangsten MONEY ,
stijgend_dalend_gelijk NVARCHAR (10)
);
--Variables get their data here.
INSERT INTO Statistiek (kwartaalnummer, beginmaand, eindmaand, orderbedrag, korting, vervoerskost, netto_ontvangsten, stijgend_dalend_gelijk)
VALUES (@huidigkwartaal, @beginmaand, @eindmaand, @orderbedrag, @korting, @vervoerskost, @netto_ontvangsten, @stijgend_dalend_gelijk);
【问题讨论】:
-
您发布了错误的代码。该错误是当您将值放入表中时。大胆猜测一下,我会说您使用 sql 将旧版本表中的数据放在新表上,该表有更多列,没有一个称为 foo。
-
嗯,是的,但是存储过程在处理任何数据之前都有
DROP TABLE,所以要么我误解了DROP TABLE的确切功能,要么存储过程不是' t考虑到这一点 -
你的数据库的排序规则是什么?运行这个:
SELECT CONVERT (varchar, SERVERPROPERTY('collation')); -
你没有从 Drop Table 中得到那个错误,你稍后会得到它。据说问题出在第 59 行和第 61 行,你只给了我们 5 行。这是创建的表与您尝试插入的数据之间的不匹配,不可能是其他原因。
-
@Sourav_Agasti
Latin1_General_CI_AS@TonyHopkinson 正如我所说,这是因为DROP TABLE没有像我预期的那样执行,我知道每个版本中的列都不同,但是两个存储过程都有DROP TABLE一开始,据我所知应该没关系吧?
标签: sql-server tsql stored-procedures ssms drop-table