不可能啊CREATE TABLE [tb]([药品货号] NVARCHAR(10),[药品名称] NVARCHAR(10),[库存数量] INT,[批号] NVARCHAR(10)) INSERT [tb] SELECT '000001',N'青霉素',2,'01' UNION ALL SELECT '000001',N'青霉素',3,'02' UNION ALL SELECT '000001',N'青霉素',5,'03' UNION ALL SELECT '000001',N'青霉素',4,'04' UNION ALL SELECT '000001',N'青霉素',6,'05'select [药品货号],[药品名称],[库存数量],[批号],identity(int,1,1) ID into # from [tb] select * from # where ID between 2 and 5 药品货号 药品名称 库存数量 批号 ID ---------- ---------- ----------- ---------- ----------- 000001 青霉素 3 02 2 000001 青霉素 5 03 3 000001 青霉素 4 04 4 000001 青霉素 6 05 5
既然#TEMP1表创建成功了,就说明第一条sql语句执行成功了,那#TEMP1中就肯定会有ID这个字段啊,在执行第二句sql时就不应该报找不到ID这个字段才对。 你直接写SELECT * FROM #TEMP1 看下
SELECT ID = IDENTITY(INT,1,1), COLUMN1, COLUMN2... INTO #TEMP1 FROM TABLENAME WHERE ... SELECT * FROM #TEMP1 WHERE ID > 0 AND ID < 200 调用存储过程?????存储过程执行成功就会有此临时表的,
难道会同时存在2个#TEMP1?理论上应该不可能的啊。
--这样试试 --在查询语句执行之前,执行以下语句:(或在查询执行完成后执行drop table #TEMP1 语句) IF OBJECT_ID('dbo.#TEMP1') IS NOT NULL DROP TABLE dbo.[#TEMP1]SELECT ID = IDENTITY(INT,1,1), COLUMN1, COLUMN2... INTO #TEMP1 FROM TABLENAME WHERE ... SELECT * FROM #TEMP1 WHERE ID > 0 AND ID < 200
在存储过程定义中加 with recompile,试一试。
--其实:楼主完全可以这样改写,不需要去创建什么临时表 SELECT TOP 200 ROW_NUMBER() OVER(ORDER BY 排序字段1, 排序字段2......, 排序字段n) AS ID, Column1,Column2,...,ColumnN from TableName;
我只是举例,也有可能是SELECT * FROM #TEMP1 WHERE ID > 200 AND ID < 400
由于现在不能重现你的错误,我只能建议使用 with recompile 试试。正在分析中
我刚才换了个临时表的名字,#TEMP1->#TEST,现在好像正常了,我再继续观察下。
经过试验,终于弄明白了。在执行存储过程前,系统会验证过程所引用的对象是否有效,再去执行存储过程。因此,如果调用存储过程的会话中存在一个与 #temp1 同名的临时表,系统便会根据此同名的临时表解析 ID 列,而不是根据在执行过程中创建的临时表进行名称解析。因此,如果存储过程中不包含 ID 列,则不会发生此错误。解决方法应该很简单,将 #TEMP1 改名,最好改为一个独一无二的名称。
可以试验一下,即使调用存储过程的会话中存在一个与 #temp1 同名的临时表,但如果存储过程定义中不包含 ID 列名(以及任何 #TEMP1 中的列名),执行存储过程时也不会发生错误。这应该是名称解析阶段的问题。而在执行阶段,由于在存储过程中创建的临时表,其作用域是存储过程,因此不会与调用存储过程的会话中存在的临时表有名称冲突问题。
INSERT [tb]
SELECT '000001',N'青霉素',2,'01' UNION ALL
SELECT '000001',N'青霉素',3,'02' UNION ALL
SELECT '000001',N'青霉素',5,'03' UNION ALL
SELECT '000001',N'青霉素',4,'04' UNION ALL
SELECT '000001',N'青霉素',6,'05'select [药品货号],[药品名称],[库存数量],[批号],identity(int,1,1) ID into # from [tb]
select * from # where ID between 2 and 5
药品货号 药品名称 库存数量 批号 ID
---------- ---------- ----------- ---------- -----------
000001 青霉素 3 02 2
000001 青霉素 5 03 3
000001 青霉素 4 04 4
000001 青霉素 6 05 5
看下
调用存储过程?????存储过程执行成功就会有此临时表的,
--这样试试
--在查询语句执行之前,执行以下语句:(或在查询执行完成后执行drop table #TEMP1 语句)
IF OBJECT_ID('dbo.#TEMP1') IS NOT NULL
DROP TABLE dbo.[#TEMP1]SELECT ID = IDENTITY(INT,1,1), COLUMN1, COLUMN2... INTO #TEMP1 FROM TABLENAME WHERE ... SELECT * FROM #TEMP1 WHERE ID > 0 AND ID < 200
--其实:楼主完全可以这样改写,不需要去创建什么临时表
SELECT TOP 200
ROW_NUMBER() OVER(ORDER BY 排序字段1, 排序字段2......, 排序字段n) AS ID,
Column1,Column2,...,ColumnN
from TableName;
我只是举例,也有可能是SELECT * FROM #TEMP1 WHERE ID > 200 AND ID < 400