1

我正在通过 MS SQL Server 中的 OpenQuery 查询进度数据库。

我有一个字段 (addr),其中包含以下格式的字符串值:

text123; text 456; text 789; text 1011

我需要在分号之前提取每个值;对于单独的列

在 T SQL 中,我将使用以下内容提取第一部分:

SELECT
SUBSTRING(addr,1,CHARINDEX(';', addr,1) - 1)
FROM MyTable

但是,在 Progress 中没有 CHARINDEX,而是 INSTR

这是我的开放查询:

SELECT * FROM OPENQUERY (MyServer, 'SELECT addr, SUBSTRING("addr",1,INSTR('';'', "addr",1) - 1) as test FROM MyTable')

但我收到以下错误:

OLE DB provider "MSDASQL" for linked server "MyServer" returned message "[DataDirect][ODBC Progress OpenEdge Wire Protocol driver]Error in row.".

我错过了什么?

4

2 回答 2

0

从 SQL92 来看Progress OpenEdge 中的 Extent/array 字段显示为用分号分隔,如果这是一个 extent/array 字段,那么您可以简单地使用:

addr[1]

如果不是,那么您可以使用instr您需要使用正确的语法。第一个参数是字符串,第二个是你想在里面找到的。请注意以下额外+ ';'内容,以确保字符串始终以分号结尾:

substr( addr, 1, instr( addr + ';', ';', 1 ) - 1 )

如果您不仅想要第一个,还想要第二个或第三个,那么它会有点棘手:

select
  addr,  
  substring( addr, 1, instr( addr + ';', ';', 1, 1 ) ) as '#1' ,
  case    
     when instr( addr, ';', 1, 1 ) > 0 then
       substring( addr, instr( addr, ';', 1, 1 ), instr( addr + ';', ';', 1, 2 ) - instr( addr, ';', 1, 1 ) )
     else 
       ''
  end as '#2' ,
  case    
     when instr( addr, ';', 1, 2 ) > 0 then 
       substring( addr, instr( addr, ';', 1, 2 ), instr( addr + ';', ';', 1, 3 ) - instr( addr, ';', 1, 2 ) )
     else 
       ''
  end as '#3'  
from ...

以上所有内容均已使用 JDBC 驱动程序从 PDSOE (Eclipse) 进行了测试。假设 OPENQUERY 在此过程中没有损坏任何东西,你应该没问题。

于 2020-02-08T15:29:13.463 回答
0

这就是我将如何处理这个...

PostgreSQL:

WITH -- YUOUR TEXT HERE:
someString AS (SELECT 'text123; text 456; text 789; text 1011' AS txt), -- Can come in as a variable
a          AS (SELECT N FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS x(N)),
iTally(N)  AS 
(
  SELECT 0 UNION ALL
  SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
  FROM   a, a AS b, a AS c, a AS d
),
ngrams(N,Token) AS
(
  SELECT     N, SUBSTRING(txt from N::integer for 1)
  FROM       iTally
  CROSS JOIN someString
  WHERE      N <= CHAR_LENGTH(txt)
)
SELECT 
  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ItemNumber,
  (N+1)                          AS ItemIndex,
  len                            AS ItemLength,
  SUBSTRING(ntxt from 1 for len) AS Item
FROM       ngrams
CROSS JOIN someString
CROSS JOIN LATERAL (VALUES(SUBSTRING(txt from (N+1)::integer for CHAR_LENGTH(txt))))  AS eg(ntxt)
CROSS JOIN LATERAL (VALUES(COALESCE(NULLIF(strpos(ntxt,';'),0),CHAR_LENGTH(ntxt))-1)) AS item(len)
WHERE N = 0 OR token LIKE ';%';

结果:

ItemNumber  ItemIndex  ItemLength  Item
----------- ---------- ----------- -----------
1           1          7           text123
2           9          9            text 456
3           19         9            text 789
4           29         9            text 101

退货商品可能需要稍微修剪一下

于 2020-02-04T20:26:40.067 回答