(1) 自动生成cursorSchema。 这样的话,后端字段长度/小数点长度,有改变时,前端能自动适应,不必
再去改CA,输入界面也适应了,方便很多。
另外,FOX9的CA/SPT在n型字段的映射长度方面也有BUG,通过下段代码一并修正。
NUMERIC定义比较
(1)无小数的情况
SQL: N 5 -> 数字全长为5. 可表达最大数字为 99999
VFPL: N 5 -> 数字全长为5. 可表达最大数字为 99999
以spt或ca,从vfp取回sql的数据时,sql端 n 5的字段, VFP端竟然是 n 7。如果用户按这个长度输入,那UPDATE时就出错了。
处理:对整数,整数部分的长度减2。
(2)有小数
SQL: N 5.2 -> 数字全长为5,其中整数部分3位, 小数点后2位。 小数点不计在长度之内。 可表达最大数字为 999.99
VFP: N 5.2 -> 数字连小数点全长为5,其中小数点后2位。 小数点计在长度之内。 可表达最大数字为 99.99 (比上面小了1位)
取回 SQL 端 n (5.2) (999.99) 字段, VFP端竟为 N 7.2 (9999.99)。即:VFP端 小数点前多了 1 位.。应是 N6.2 才对.
Local cSql,cKeyWord,nArea,cSchema,i,
cType
,cTmp,nTmp,cLenght,cDecimal
nArea = Select ()
*-- 如curorSchema为空 且 没有改过相关属性 --> 自动生成 curorSchema
If Not ( (Pemstatus(This, ' __VFPSetup', 5) And This.__VFPSetup!=0 ) Or Empty(This.SelectCmd) )
If NOT This.UseCursorSchema
cSchema = ' '
cKeyWord = ' select,from,where,order by,having'
TEXT to cSql
Select << gcGetSubClause(this.SelectCmd,cKeyWord, ' select')>>
from << gcGetSubClause(this.SelectCmd,cKeyWord, ' from')>>
where 1 = 2
ENDTEXT
If Not glSql( 0 ,cSql)
Select (nArea)
Return .F.
Endif
*- 字段类别转换 t -> d, G -> W(blob)
For i = 1 To Fcount()
cType = gcFieldType(i, ' ',2)
cType = Icase( Left ( cType , 1 ) = ' G', 'W',;
Left ( cType , 1 ) = ' T' And ( Not '时间' $ Field(i) And Not 'TIME' $ Field(i)) , 'D'+Substr(cType,2),;
.T., cType )
If GetWordNum( cType , 1 , ' (,)')=='N'
*- 修正VFP sp2 beta 的bug
*- N( 5 ) -> N( 3 )
*- N( 5 , 2 ) -> N( 4 , 2 )
cDecimal = GetWordNum( cType , 3 , ' (,)')
cLenght = Alltrim( Str ( Val (GetWordNum( cType , 2 , ' (,)')) - Iif(cDecimal='0',2,1) ) ) &&
cType = ' N(' + cLenght + ', ' +cDecimal + ')'
EndIf
cSchema = cSchema + ' ,' + Field(i) + ' ' + cType
Next
cSchema = Substr(cSchema, 2 )
This.CursorSchema = cSchema
This.UseCursorSchema = .T.
Endif
Endif
*-- EOS -----------------------------------------
Select (nArea)
nArea = Select ()
*-- 如curorSchema为空 且 没有改过相关属性 --> 自动生成 curorSchema
If Not ( (Pemstatus(This, ' __VFPSetup', 5) And This.__VFPSetup!=0 ) Or Empty(This.SelectCmd) )
If NOT This.UseCursorSchema
cSchema = ' '
cKeyWord = ' select,from,where,order by,having'
TEXT to cSql
Select << gcGetSubClause(this.SelectCmd,cKeyWord, ' select')>>
from << gcGetSubClause(this.SelectCmd,cKeyWord, ' from')>>
where 1 = 2
ENDTEXT
If Not glSql( 0 ,cSql)
Select (nArea)
Return .F.
Endif
*- 字段类别转换 t -> d, G -> W(blob)
For i = 1 To Fcount()
cType = gcFieldType(i, ' ',2)
cType = Icase( Left ( cType , 1 ) = ' G', 'W',;
Left ( cType , 1 ) = ' T' And ( Not '时间' $ Field(i) And Not 'TIME' $ Field(i)) , 'D'+Substr(cType,2),;
.T., cType )
If GetWordNum( cType , 1 , ' (,)')=='N'
*- 修正VFP sp2 beta 的bug
*- N( 5 ) -> N( 3 )
*- N( 5 , 2 ) -> N( 4 , 2 )
cDecimal = GetWordNum( cType , 3 , ' (,)')
cLenght = Alltrim( Str ( Val (GetWordNum( cType , 2 , ' (,)')) - Iif(cDecimal='0',2,1) ) ) &&
cType = ' N(' + cLenght + ', ' +cDecimal + ')'
EndIf
cSchema = cSchema + ' ,' + Field(i) + ' ' + cType
Next
cSchema = Substr(cSchema, 2 )
This.CursorSchema = cSchema
This.UseCursorSchema = .T.
Endif
Endif
*-- EOS -----------------------------------------
Select (nArea)
(2) 加一个方法 _c取字段对照表,返回 alias.field 与 select 语句中 a.XX 的对照表,多用于 多条件生成器中。
*---
取出 a.xx
<->
XX 对照表
*- 遇到 select * 的情况, 暂不管了
Local cTmp,i,oCA,c对照表,cCA字段名
Local cCA字段名,c列标题,c字段类型,c列标题,cTmp,c前端字段名,nPosi,cSelect
cSelect = gcGetSubClause(this.SelectCmd, ' select,from,where,order by','select')
cSelect = Strtran(cSelect, ' distinct','')
c对照表 = ' '
For i = 1 to GetWordCount(cSelect, ' ,')
cTmp = Alltrim( GetWordNum(cSelect,i, ' ,'),1,Chr(9),Chr(10),Chr(13),Chr(32))
nPos = Atc( ' as',cTmp)
If nPos = 0
cField = cTmp
cCaption = Iif (At( ' .',cTmp)>0,GetWordNum(cTmp,2,'.'),cTmp)
Else
cField = Alltrim(Substr(cTmp, 1 ,nPos - 1 ))
cCaption = Alltrim(Substr(cTmp,nPos + 2 ))
EndIf
c对照表 = c对照表 + ' ,'+ Textmerge("<<cCaption>>,<<cField>>,<<Type(cCaption)>>")
Next
c对照表 = Substr(c对照表, 2 )
*--
Return c对照表
*- 遇到 select * 的情况, 暂不管了
Local cTmp,i,oCA,c对照表,cCA字段名
Local cCA字段名,c列标题,c字段类型,c列标题,cTmp,c前端字段名,nPosi,cSelect
cSelect = gcGetSubClause(this.SelectCmd, ' select,from,where,order by','select')
cSelect = Strtran(cSelect, ' distinct','')
c对照表 = ' '
For i = 1 to GetWordCount(cSelect, ' ,')
cTmp = Alltrim( GetWordNum(cSelect,i, ' ,'),1,Chr(9),Chr(10),Chr(13),Chr(32))
nPos = Atc( ' as',cTmp)
If nPos = 0
cField = cTmp
cCaption = Iif (At( ' .',cTmp)>0,GetWordNum(cTmp,2,'.'),cTmp)
Else
cField = Alltrim(Substr(cTmp, 1 ,nPos - 1 ))
cCaption = Alltrim(Substr(cTmp,nPos + 2 ))
EndIf
c对照表 = c对照表 + ' ,'+ Textmerge("<<cCaption>>,<<cField>>,<<Type(cCaption)>>")
Next
c对照表 = Substr(c对照表, 2 )
*--
Return c对照表