我有几个FoxPro prg已经使用了很多年。现在我们正在慢慢尝试实现SQL Server的使用,我正试图用prg实现它。我已经为我们正在使用的.dbf文件创建了2个链接服务器,并且一切都很好。现在我想弄清楚如何转换或翻译prg代码,以便我可以在Crystal Reports查询中使用它。我知道基本的SQL查询,如果我用简单的查询测试链接的服务器,它在Crystal中工作正常。但是有些prg是非常复杂的并且使用了游标,而这正是我所痴迷的。这是一个例子:
Select soheader.partno As Item,;
soheader.sono As sono,;
soheader.rev As sorev,;
soheader.sqty As sqty,;
soheader.need_date As needdate,;
soheader.priority,;
soheader.salesno,;
soheader.crea_date,;
soheader.start_date,;
soheader.remark1,;
soheader.remark2,;
soheader.instr1,;
soheader.instr2,;
soheader.plandate,;
soheader.rev,;
soheader.fgloc,;
soheader.mtlloc,;
soheader.solineno,;
soheader.Userid,;
soheader.part_desc,;
Soroute.opno As routeopno,;
Soroute.loadcenter,;
Soroute.Descrip As Routedes,;
Immaster.misc04 As lottrack,;
immaster.upccode As upccode;
FROM soheader Inner Join Soroute On soheader.sono = Soroute.sono;
LEFT Join immaster On soheader.partno = immaster.Item;
Into Cursor c1
Select c1.*,;
Somater.partno As partno,;
STR(Asc(Somater.Phanref),3)As Phanref,;
STR(Asc(Somater.Phanid),3)As Phanid,;
VAL(Somater.qty_assy) As qty_assy,;
VAL(Somater.qty_aloc) As qty_aloc,;
Somater.Delmark As Delmark;
FROM c1 Left Join Somater On c1.sono = Somater.sono And c1.routeopno = Somater.opno;
INTO Cursor c2
Select c2.*,;
immaster.Descrip As Descrip,;
immaster.stockum As stockum,;
immaster.misc04 As misc04,;
immaster.lotstat As lotstat;
FROM c2 Left Join immaster On c2.partno = immaster.Item;
Into Cursor c3
Select c3.*,;
imstock.lonhand As lotqty,;
imstock.locid As lotloc,;
imstock.lot As lotnum;
FROM c3 Left Join imstock On imstock.Item = c3.partno AND c3.mtlloc = imstock.locid;
Into Cursor c4
Select c4.*, Iif(Empty(Bmrev.fgparent), Bmrev.itemparent, Bmrev.fgparent ) As fg;
FROM c4 Left Join Bmrev On c4.Item + c4.sorev = Bmrev.itemparent + Bmrev.rev;
into Cursor C5
Select C5.*, bmsl.findno, bmsl.scrpad;
FROM C5 Left Join bmsl On C5.fg + C5.partno + C5.sorev = bmsl.itemparent + bmsl.itemchild + bmsl.rev;
INTO Cursor C6
如何在SQL中处理不同的游标,以便得到正确的最终结果?
编辑:
经过大卫的一些帮助,我们已经到了查询有效的地步,但现在从varchar到bigint的转换存在问题。我已经更改了查询以摆脱一些问题,这是当前的查询:
SELECT
SOH.partno AS Item
,SOH.sono AS sono
,SOH.rev AS sorev
,SOH.sqty AS sqty
,SOH.need_date AS needdate
,SOH.priority
,SOH.salesno
,SOH.crea_date
,SOH.start_date
,SOH.remark1
,SOH.remark2
,SOH.instr1
,SOH.instr2
,SOH.plandate
,SOH.rev
,SOH.fgloc
,SOH.mtlloc
,SOH.solineno
,SOH.Userid
,SOH.part_desc
,SOR.opno AS routeopno
,SOR.loadcenter
,SOR.Descrip AS Routedes
,SO.partno AS partno
,STR(ASCII(SO.Phanref), 3) AS Phanref
,STR(ASCII(SO.Phanid), 3) AS Phanid
,(
CASE WHEN ISNUMERIC(SO.qty_assy) = 1
THEN CONVERT(DECIMAL, SO.qty_assy)
ELSE NULL
END
) AS qty_assy
,(
CASE WHEN ISNUMERIC(SO.qty_aloc) = 1
THEN CONVERT(DECIMAL, SO.qty_aloc)
ELSE NULL
END
) AS qty_aloc
,SO.Delmark AS Delmark
,IMM.misc04 AS lottrack
,IMM.upccode AS upccode
,IMM.Descrip AS Descrip
,IMM.stockum AS stockum
,IMM.misc04 AS misc04
,IMM.lotstat AS lotstat
,IMS.lonhand AS lotqty
,IMS.locid AS lotloc
,IMS.lot AS lotnum
,(
CASE WHEN ISNULL(BMR.fgparent, 0) = 0
THEN BMR.itemparent
ELSE BMR.fgparent
END
) AS fg
,BMS.findno
,BMS.scrpad
FROM [LinkedWS]...[Soheader] AS SOH
INNER JOIN [LinkedWS]...[Soroute] AS SOR
ON SOH.sono = SOR.sono
LEFT OUTER JOIN [LinkedAC]...[immaster] AS IMM
ON SOH.partno = IMM.Item
LEFT OUTER JOIN [LinkedWS]...[Somater] AS SO
ON 1 = 1
AND SOH.sono = SO.sono
AND SOR.opno = SO.opno
LEFT OUTER JOIN [LinkedAC]...[imstock] AS IMS
ON 1 = 1
AND SOH.partno = IMS.item
AND SOH.mtlloc = IMS.locid
LEFT OUTER JOIN [LinkedWS]...[Bmrev] AS BMR
ON SOH.partno + SOH.rev = BMR.itemparent + BMR.rev
LEFT OUTER JOIN [LinkedWS]...[bmsl] AS BMS
ON (
CASE WHEN ISNULL(BMR.fgparent, 0) = 0
THEN BMR.itemparent
ELSE BMR.fgparent
END
) + SO.partno + SOH.rev = BMS.itemparent + BMS.itemchild + BMS.rev
当我运行此查询时,我收到错误,它无法将varchar转换为bigint。如果我将bigint更改为int,则会收到错误“Msg 245,Level 16,State 1,Line 1 将varchar值'0.350'转换为数据类型int时转换失败。“ 字段qty_assy和qty_aloc都是FoxPro表中的字符字段,但据我所知,这些字段中没有字符。虽然0.350前面的领先空间让我相信我需要添加一个TRIM来摆脱它们?
编辑2:
将转换从BIGINT更改为DECIMAL,这解决了问题。我仍然收到一条错误消息,但似乎没有任何影响。问题解决了!
答案 0 :(得分:3)
游标代表临时表(有关更多信息,请查看this article)。
SQL Server的已翻译代码如下所示:
SELECT
SOH.partno AS Item
,SOH.sono AS sono
,SOH.rev AS sorev
,SOH.sqty AS sqty
,SOH.need_date AS needdate
,SOH.priority
,SOH.salesno
,SOH.crea_date
,SOH.start_date
,SOH.remark1
,SOH.remark2
,SOH.instr1
,SOH.instr2
,SOH.plandate
,SOH.rev
,SOH.fgloc
,SOH.mtlloc
,SOH.solineno
,SOH.Userid
,SOH.part_desc
,SOR.opno AS routeopno
,SOR.loadcenter
,SOR.Descrip AS Routedes
,SO.partno AS partno
,STR(ASCII(SO.Phanref), 3) AS Phanref
,STR(ASCII(SO.Phanid), 3) AS Phanid
,IIF(ISNUMERIC(SO.qty_assy) = 1, CONVERT(BIGINT, SO.qty_assy), NULL) AS qty_assy
,IIF(ISNUMERIC(SO.qty_aloc) = 1, CONVERT(BIGINT, SO.qty_aloc), NULL) AS qty_aloc
,SO.Delmark AS Delmark
,IMM.misc04 AS lottrack
,IMM.upccode AS upccode
,IMM.Descrip AS Descrip
,IMM.stockum AS stockum
,IMM.misc04 AS misc04
,IMM.lotstat AS lotstat
,IMS.lonhand AS lotqty
,IMS.locid AS lotloc
,IMS.lot AS lotnum
,IIF(ISNULL(BMR.fgparent, 0) = 0, BMR.itemparent, BMR.fgparent) AS fg
,BMS.findno
,BMS.scrpad
FROM Soheader AS SOH
INNER JOIN Soroute AS SOR
ON SOH.sono = SOR.sono
LEFT OUTER JOIN immaster AS IMM
ON SOH.partno = IMM.Item
LEFT OUTER JOIN Somater AS SO
ON 1 = 1
AND SOH.sono = SO.sono
AND SOR.opno = SO.opno
LEFT OUTER JOIN imstock AS IMS
ON 1 = 1
AND SOH.partno = IMS.Item
AND SOH.mtlloc = IMS.locid
LEFT OUTER JOIN Bmrev AS BMR
ON SOH.Item + SOH.sorev = BMR.itemparent + BMR.rev
LEFT OUTER JOIN bmsl AS BMS
ON IIF(ISNULL(BMR.fgparent, 0) = 0, BMR.itemparent, BMR.fgparent) + SO.partno + SOH.sorev = BMS.itemparent + BMS.itemchild + BMS.rev
我猜测fgparent列有数字数据类型,为什么行
Empty(Bmrev.fgparent)
已翻译为
ISNULL(BMR.fgparent, 0) = 0
如果是字母数字,可以根据this link中提供的信息更改转化。
功能的等同性
FoxPro SQL SQL SERVER
----------------------------
STR STR
ASC ASCII
VAL CONVERT(BIGINT, ...)
IIF IIF
有用的链接:
修改强>
,请检查以下代码SELECT
SOH.partno AS Item
,SOH.sono AS sono
,SOH.rev AS sorev
,SOH.sqty AS sqty
,SOH.need_date AS needdate
,SOH.priority
,SOH.salesno
,SOH.crea_date
,SOH.start_date
,SOH.remark1
,SOH.remark2
,SOH.instr1
,SOH.instr2
,SOH.plandate
,SOH.rev
,SOH.fgloc
,SOH.mtlloc
,SOH.solineno
,SOH.Userid
,SOH.part_desc
,SOR.opno AS routeopno
,SOR.loadcenter
,SOR.Descrip AS Routedes
,SO.partno AS partno
,STR(ASCII(SO.Phanref), 3) AS Phanref
,STR(ASCII(SO.Phanid), 3) AS Phanid
,(
CASE WHEN ISNUMERIC(SO.qty_assy) = 1
THEN CONVERT(BIGINT, SO.qty_assy)
ELSE NULL
END
) AS qty_assy
,(
CASE WHEN ISNUMERIC(SO.qty_aloc) = 1
THEN CONVERT(BIGINT, SO.qty_aloc)
ELSE NULL
END
) AS qty_aloc
,SO.Delmark AS Delmark
,IMM.misc04 AS lottrack
,IMM.upccode AS upccode
,IMM.Descrip AS Descrip
,IMM.stockum AS stockum
,IMM.misc04 AS misc04
,IMM.lotstat AS lotstat
,IMS.lonhand AS lotqty
,IMS.locid AS lotloc
,IMS.lot AS lotnum
,(
CASE WHEN ISNULL(BMR.fgparent, 0) = 0
THEN BMR.itemparent
ELSE BMR.fgparent
END
) AS fg
,BMS.findno
,BMS.scrpad
FROM Soheader AS SOH
INNER JOIN Soroute AS SOR
ON SOH.sono = SOR.sono
LEFT OUTER JOIN immaster AS IMM
ON SOH.partno = IMM.Item
LEFT OUTER JOIN Somater AS SO
ON 1 = 1
AND SOH.sono = SO.sono
AND SOR.opno = SO.opno
LEFT OUTER JOIN imstock AS IMS
ON 1 = 1
AND SOH.partno = IMS.Item
AND SOH.mtlloc = IMS.locid
LEFT OUTER JOIN Bmrev AS BMR
ON SOH.Item + SOH.sorev = BMR.itemparent + BMR.rev
LEFT OUTER JOIN bmsl AS BMS
ON (
CASE WHEN ISNULL(BMR.fgparent, 0) = 0
THEN BMR.itemparent
ELSE BMR.fgparent
END
) + SO.partno + SOH.sorev = BMS.itemparent + BMS.itemchild + BMS.rev
答案 1 :(得分:0)
与VFP游标保持类似的另一个快捷方式是让您的SQL存储过程(或其他)通过“#Cursor”使用临时表。您使用
的语法非常相似select a.*
into #C_TempCursorInSQL
from blah a
where conditions..
select b.*
into #C_AnotherCursor
from #C_TempCursorInSQL b
where otherConditions...
等等。所以你仍然可以尝试保持相似性,一次查询和处理小块。