首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

100分:大抛卖啦 走过路过不要错过,一个sp有关问题

2012-01-21 
100分:大抛卖啦 走过路过不要错过,一个sp问题有个SP执行要化十多分钟,代码如下:IFEXISTS(SELECT*FROMdbo.s

100分:大抛卖啦 走过路过不要错过,一个sp问题
有个SP执行要化十多分钟,代码如下:
IF   EXISTS   (SELECT   *   FROM   dbo.sysobjects   WHERE   id   =   OBJECT_ID(N '[dbo].[usp_StatisticsTotalPurchase] ')   AND   OBJECTPROPERTY(id,   N 'IsProcedure ')   =   1)
DROP   PROC   [dbo].[usp_StatisticsTotalPurchase]
GO

CREATE   PROC   [dbo].[usp_StatisticsTotalPurchase]
@Reference   INT,
@BeginDate   DATETIME,
@EndDate   DATETIME,
@ErrorNumber   INT   OUTPUT,
@ErrorInfo   NVARCHAR(200)   OUTPUT
AS
SET   NOCOUNT   ON;

DECLARE   @Profit   MONEY
,   @RefStandardCost   MONEY
,   @PartID   NVARCHAR(60)
,   @Mode   NVARCHAR(10)
,   @Date   DATETIME
,   @YearMonth   NVARCHAR(6);

--得到利润率
SELECT   @Profit   =   Profit
FROM   dbo.Profit
WHERE   Active   =   1;

IF   @Profit   IS   NULL
BEGIN
SELECT   @ErrorNumber   =   110,   @ErrorInfo   =   N 'Profit   data   not   set. ';
SET   NOCOUNT   OFF;
RETURN   CAST(0   AS   BIT);
END;

--确定统计的部件
DECLARE   @Parts   TABLE
(
PartID   NVARCHAR(60)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL   PRIMARY   KEY,
RefStdCost   MONEY
);

IF   LEN(CAST(@Reference   AS   NVARCHAR))   =   6
INSERT   INTO   @Parts   (PartID)
SELECT   DISTINCT   PartID
FROM   dbo.StandardCost
WHERE   IsPurchased   =   1
AND   YEAR([Date])   *   100   +   MONTH([Date])   <=   @Reference;
ELSE
INSERT   INTO   @Parts   (PartID)
SELECT   DISTINCT   PartID
FROM   dbo.StandardCost
WHERE   IsPurchased   =   1
AND   YEAR([Date])   <=   @Reference;

DELETE   @Parts
FROM   @Parts   p
INNER   JOIN
(
SELECT   PartID
FROM   dbo.StandardCost
GROUP   BY   PartID
HAVING   SUM(Price)   =   0
)   c
ON   p.PartID   =   c.PartID;

DELETE   @Parts
FROM   @Parts   p
WHERE   NOT   EXISTS
(
SELECT   1
FROM   iERP72tech.dbo.POM   pom
INNER   JOIN   iERP72tech.dbo.POI   poi
ON   poi.POI_PurchOrderID   =   pom.POM_PurchOrderID
INNER   JOIN   iERP72tech.dbo.POD   pod
ON   pod.POD_PurchOrderID   =   pom.POM_PurchOrderID
AND   pod.POD_POLineNbr   =   poi.POI_POLineNbr
WHERE   poi.POI_LineNbrTypeCode   =   N 'Item '
AND   pod.POD_POUnitPrice   >   0
AND   pom.POM_PurchOrderDate   > =   @BeginDate
AND   pom.POM_PurchOrderDate   <   DATEADD(DAY,   1,   @EndDate)
AND   poi.POI_ItemID   COLLATE   Chinese_PRC_CI_AS   =   p.PartID
);

IF   NOT   EXISTS   (SELECT   1   FROM   @Parts)
BEGIN
SELECT   @ErrorNumber   =   110,   @ErrorInfo   =   N 'Standard   cost   in   reference   period   not   exists. ';
SET   NOCOUNT   OFF;
RETURN   CAST(0   AS   BIT);
END;

--得到参照标准成本


IF   LEN(CAST(@Reference   AS   NVARCHAR))   =   6
UPDATE   @Parts
SET   RefStdCost   =   sc.Price
FROM   @Parts   p
INNER   JOIN
(
SELECT   PartID,   AVG(Price)   Price
FROM   dbo.StandardCost
WHERE   YEAR([Date])   *   100   +   MONTH([Date])   =   @Reference
GROUP   BY   PartID
)   sc
ON   p.PartID   =   sc.PartID;
ELSE
UPDATE   @Parts
SET   RefStdCost   =   sc.Price
FROM   @Parts   p
INNER   JOIN
(
SELECT   PartID,   AVG(Price)   Price
FROM   dbo.StandardCost   sc
WHERE   YEAR([Date])   =   @Reference
GROUP   BY   PartID
)   sc
ON   p.PartID   =   sc.PartID;

IF   LEN(CAST(@Reference   AS   NVARCHAR))   =   6
UPDATE   @Parts
SET   RefStdCost   =   c.Price
FROM   @Parts   p
INNER   JOIN
(
SELECT   PartID,   MAX([Date])   MaxDate
FROM   dbo.StandardCost
WHERE   YEAR([Date])   *   100   +   MONTH([Date])   <   @Reference
GROUP   BY   PartID
)   s
ON   s.PartID   =   p.PartID
INNER   JOIN   dbo.StandardCost   c
ON   c.PartID   =   s.PartID   AND   c.[Date]   =   s.MaxDate
WHERE   p.RefStdCost   IS   NULL;
ELSE
UPDATE   @Parts
SET   RefStdCost   =   c.Price
FROM   @Parts   p
INNER   JOIN
(
SELECT   PartID,   MAX([Date])   MaxDate
FROM   dbo.StandardCost
WHERE   YEAR([Date])   <   @Reference
GROUP   BY   PartID
)   s
ON   s.PartID   =   p.PartID
INNER   JOIN   dbo.StandardCost   c
ON   c.PartID   =   s.PartID   AND   c.[Date]   =   s.MaxDate
WHERE   p.RefStdCost   IS   NULL;

SELECT   @RefStandardCost   =   AVG(RefStdCost)
FROM   @Parts;

--PRINT   '@RefStandardCost   =   '   +   CAST(@RefStandardCost   AS   NVARCHAR(20));

[解决办法]
............好长~~先路过再看看
[解决办法]
自查询1秒出来很正常,Update时间比子查询长,看看索引之类的是不是可以优化
[解决办法]
/*****************************************
如果注释下面三句话,则2-3秒就可以执行完成
加上下面一句,则十几分都出不来
*****************************************/

--存在采购价格的部件取平均值
UPDATE @Price
SET ActualPrice = t.ActualPrice
FROM @Price p
INNER JOIN
(
/***********************
单独执行只要1秒钟
************************/
=========没看明白,你说的三行是哪三行
[解决办法]
我想你的时间肯定是花在@Price表变量和后面很长一段查询的INNER JOIN上了

我想你能不能先把后面是用表变量和一个结果集做INNER JOIN我没试过
你看能不能把表变量换成一个临时表试试,也许会好一点

[解决办法]
/*****************************************
如果注释下面三句话,则2-3秒就可以执行完成
加上下面一句,则十几分都出不来
*****************************************/

循环里面有频繁的UPDATE操作,自然慢。
可以想办法把循环里的UPDATE语句改成使用动态SQL语句,再指定循环多少次执行一次EXECUTE(动态SQL语句)



[解决办法]
学习
[解决办法]
up
[解决办法]
的确挺长的。
[解决办法]
路过学习
[解决办法]
你的代码也太长了,要看千年啊

[解决办法]
可以试试把UPDATE后的子查询,存到临时表里,然后再用临时表来更新数据
[解决办法]
因为你的UPDATE现在是一个相关子查询来进行更新,是一个循环每次更新都要执行一便子查询,每次1秒*表中的数据,自然很慢

热点排行