PROGRESS DB извлечь строку между точками с запятой - Ошибка функции INSTR - PullRequest
1 голос
/ 04 февраля 2020

Я запрашиваю базу данных Progress через OpenQuery на сервере MS SQL.

У меня есть поле (addr), которое содержит строковое значение в следующем формате:

text123; text 456; text 789; text 1011

Мне нужно извлечь каждое значение перед точкой с запятой; для отдельных столбцов

В T SQL я бы сделал это, используя приведенное ниже, чтобы извлечь первую часть:

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

Однако в Progress нет CHARINDEX, но INSTR

Это мой Openquery:

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.".

Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 08 февраля 2020

Поля экстента / массива в Progress OpenEdge также показаны как разделенные точкой с запятой при просмотре из SQL92, если это поле экстента / массива, то вы можете просто используйте:

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 ...

Все вышеперечисленное было протестировано на PDSOE (Eclipse) с использованием драйвера JDB C. Предполагая, что OPENQUERY ничего не портит по пути, у вас все будет хорошо.

0 голосов
/ 04 февраля 2020

Вот как бы я справился с этим ...

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

Для возврата товара может потребоваться небольшая обрезка

...