2012-10-23 13 views
11

Mam następujący opis: "Product Product Maker XYZ - Size" i chciałbym otrzymać z tego tylko wartość "Product Name XYZ". Gdyby to był tylko jeden wiersz, nie miałbym problemu z używaniem SUBSTRINGA, ale mam tysiące rekordów i chociaż wartość początkowa Sample Maker jest taka sama dla wszystkich produktów, nazwa produktu może być inna i nie chcę niczego po łącznik.Niepoprawny parametr długości przekazany do funkcji LEFT lub SUBSTRING

Do tej pory wygenerowałem błąd w nagłówku tego pytania.

SELECT i.Itemid, 
     RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 25, (SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)))))) AS ProductDescriptionAbbrev, 
     CHARINDEX('-', i.ShortDescription, 0) - 25 as charindexpos 
FROM t_items i 

otrzymuję „typ danych Argument varchar jest nieprawidłowy dla argumentu 3 funkcja podciągu”

Jak widać, jestem coraz wartość ostatniego wiersza w sql, ale gdy próbuję i podłącz go do funkcji SUBSTRINGU Otrzymuję różne problemy.

Odpowiedz

18

Istnieje duża szansa, że ​​masz wiersze, w których brakuje "-", co powoduje błąd. Spróbuj tego ...

SELECT i.Itemid, 
    SUBSTRING(i.ShortDescription, 22, CHARINDEX('-', i.ShortDescription+'-', 22)) AS ProductDescriptionAbbrev, 
FROM t_items i 
+1

Zgłoszony błąd ("Argumentowy typ danych varchar jest nieprawidłowy dla argumentu 3 funkcji substring") jest oparty na składni instrukcji SQL OP, a nie na pobranych danych. – HABO

+0

Nie szukaj obraźliwego wiersza tylko w pobranych danych. Może znajdować się w bazowym zbiorze danych przed klauzulą ​​WHERE. To sprawia, że ​​trudno jest znaleźć obraźliwy wiersz, ale ta metoda rozwiązuje go w każdym z tych zdarzeń. – pghcpa

1

Twoje pierwsze połączenie z SUBSTRING określa długość SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)).

Można spróbować:

declare @t_items as Table (ItemId Int Identity, ShortDescription VarChar(100)) 
insert into @t_items (ShortDescription) values 
    ('Sample Product Maker Product Name XYZ - Size') 

declare @SkipLength as Int = Len('Sample Product Maker') 

select ItemId, 
    RTrim(LTrim(Substring(ShortDescription, @SkipLength + 1, CharIndex('-', ShortDescription, @SkipLength) - @SkipLength - 1))) as ProductDescriptionAbbrev 
    from @t_items 
+0

Czy to jest odpowiedź? Próbowałem różnych rzeczy, aby to zadziałało. Najlepiej byłoby, gdyby charindexpos był trzecim argumentem poprzedniego stwierdzenia, ale to też nie działało. – brianhevans

1

Można też rozebrać się tekst Sample Product Maker i go stamtąd:

SELECT RTRIM(LEFT(
    LTRIM(REPLACE(i.ShortDescription, 'Sample Product Maker', '')), 
     CHARINDEX('-', LTRIM(REPLACE(i.ShortDescription, 'Sample Product Maker', 
    ''))) - 1)) 
AS ShortDescription 
+0

To daje mi dokładnie ten sam problem, który miałem wcześniej i nie jest to naprawdę to, o co prosiłem ... – brianhevans

+1

Nie, nie jest. Daje to prawidłowy wynik. Twoim pierwotnym problemem było użycie ciągu znaków zamiast int dla trzeciego pingu pierwszego PODŁOŻA. I począwszy od pozycji 25 zamiast 22. – GilM

+0

Odpowiedź na to opierała się na fakcie, że niektóre z moich ciągów znaków nie miały "-", więc zwracałem wartość ujemną do podciągu i to nie zadziała. Szkoda, że ​​był lepszy deskryptor błędu.dzięki – brianhevans

0

Wygląda jak chcesz coś takiego (22, nie 25):

SELECT i.Itemid, 
     RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 22, CHARINDEX('-', i.ShortDescription)-22))) AS ProductDescriptionAbbrev, 
     CHARINDEX('-', i.ShortDescription)-22 as charindexpos 
FROM t_items i 
1

Problemem jest to, że zewnętrzna wywołanie SUBSTRING przekazywana jest typ danych znak od wewnętrznej SUBSTRING rozmowy w trzecim parametrze.

            +--This call does not return an integer type 
SELECT i.Itemid,         V 
    RTRIM(LTRIM(SUBSTRING(i.ShortDescription, 25, (SUBSTRING(i.ShortDescription, 25, CHARINDEX('-', i.ShortDescription, 25)))))) AS ProductDescriptionAbbrev, 
    CHARINDEX('-', i.ShortDescription, 0) - 25 as charindexpos 
FROM t_items i 

Trzeci parametr musi zostać oceniony na żądaną długość. Być może miałeś na myśli LEN(SUBSTRING(...))?

0

Chcecie:

LEFT(i.ShortDescription, isnull(nullif(CHARINDEX('-', i.ShortDescription),0) - 1, 8000)) 

pamiętać, że dobrą praktyką jest, aby owinąć charindex(...) tych i patindex(...) 's ze nullif(...,0), a następnie obsłużyć null sprawy w razie potrzeby (czasami null jest odpowiedni wynik, w tym przypadku chcemy cały tekst, więc my isnull(...,8000) dla długości chcemy).

Powiązane problemy