为什么 SQL 在使用 right 函数时会截断字符串的右侧?

Why would SQL truncate the right-side of a string when using the right function?

我有一个包含许多过时文件位置的数据库。过时文件位置和正确位置之间的区别只是地址的左侧。因此,我试图将左侧取下并用正确的字符串替换它。但是,我无法到达那里,因为我的查询正在更改地址的右侧。

此查询是使用“vfpoledb”进行的。

SELECT RIGHT(LINK,LEN(LINK)-8) ,LEN(LINK)-8,RIGHT(LINK,77),LINK 
FROM LINKSTORE 
WHERE DOCLBL = "V46145002A"

此查询 return 如下:

EXP1:

\SHARES\DATA\QMS\QMS DATA\TRACKING FILES\REMOTEENTRIES\V46145 216447

EXP2:

 77

EXP3:

\SHARES\DATA\QMS\QMS DATA\TRACKING FILES\REMOTEENTRIES\V46145 216447-002A.PDF

LINK:

\SERVER\SHARES\DATA\QMS\QMS DATA\TRACKING FILES\REMOTEENTRIES\V46145 216447-002A.PDF

我不明白为什么 EXP1 和 EXP3 给出不同的结果。 EXP3 就是我要找的 EXP1 到 return。如果我能做到这一点,我可以附加正确的左侧并创建一个更新查询来修复所有问题。

编辑:

即使将查询更改为:

SELECT RIGHT(LINK,LEN(LINK)) ,LEN(LINK)-8,RIGHT(LINK,77),LINK 
FROM LINKSTORE 
WHERE DOCLBL = "V46145002A"

link还是在同一点截断,这很奇怪,因为expression_3仍然使用Right(),但手动提供长度而不是使用Len()不这样做。

此外,似乎当我 运行 查询包含所有结果时:

SELECT RIGHT(LINK,LEN(LINK)) ,LEN(LINK)-8,RIGHT(LINK,77),LINK 
FROM LINKSTORE 
WHERE 1=1

即使 Exp2Link 的大小不同,Exp1 编辑的所有值 return 的长度都相等。

所以回到问题,如果我不能将它们分开,我如何运行查询用正确的服务器替换左侧?

好吧,这很棘手,我 20 年前做过一些 Foxpro,但手边没有。

你的 SELECT 声明对我来说没问题。在 Thomas G created this DbFiddle 问题下的评论中,它表明在 'normal' dbms 中,您的 SELECT 语句给出了您期望的结果:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=37047d2b7efb91aaa029fa0fb98eea24

所以问题一定是 FoxPro/dBase 具体问题,而不是你的 SELECT 语句的问题。

阅读我看到有人说 FoxPro 在 table 字段上使用 RIGHT() 或 LEN() 时总是使用 ALLTRIM(),因为返回的数据用空格填充。我不知道这会如何导致您所看到的确切错误,但您可以试试这个:

SELECT RIGHT(ALLTRIM(LINK),LEN(ALLTRIM(LINK))-8) ,LEN(ALLTRIM(LINK))-8,RIGHT(ALLTRIM(LINK),77),ALLTRIM(LINK)
FROM LINKSTORE 
WHERE DOCLBL = "V46145002A"

编辑:好的,我有一个更好的主意 - 您的结果集中还有其他行吗?

根据这个:https://www.tek-tips.com/viewthread.cfm?qid=1706948 ...当你在 FoxPro 中执行 SELECT (expr) 时,无论第一行中 expr 的长度成为那个 [=34= 的最大长度] 因此所有后续行都被截断为该长度。以一种疯狂的 1970 年代的方式说得通。

因此,也许您在我们正在讨论的数据之上有一行数据,其长度为 68 个字符,因此每个后续值都会被截断为该长度。

解决方法是用 CAST 或 PADR 填充表达式结果:

SELECT PADR(RIGHT(ALLTRIM(LINK),LEN(ALLTRIM(LINK))-8),100),LEN(ALLTRIM(LINK))-8,PADR(RIGHT(ALLTRIM(LINK),77),100),LINK
    FROM LINKSTORE 
    WHERE DOCLBL = "V46145002A"

或没有 ALLTRIM()

SELECT PADR(RIGHT(LINK,LEN(LINK)-8),100),LEN(LINK)-8,PADR(RIGHT(LINK,77),100),LINK
    FROM LINKSTORE 
    WHERE DOCLBL = "V46145002A"