SQL中的三元运算符?“传递给 LEFT 或 SUBSTRING 函数的长度参数无效" [英] Ternary operator in SQL? "invalid length parameter passed to the LEFT or SUBSTRING function"

查看:58
本文介绍了SQL中的三元运算符?“传递给 LEFT 或 SUBSTRING 函数的长度参数无效"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,这个误导性的主题,我不知道如何用词更好.因为我主要是一名软件开发人员,所以我想到了三元运算符,我遇到了以下问题.

Sorry for this misleading subject, i didn't know how to word better. Because i'm mainly a software-developer, the ternary operator comes to my mind with my following problem.

我需要找到通过可为空的外键(modModeltabSparePart)链接两个表的最可靠方法.两者之间唯一的相似之处是模型的名称和备件的描述(tabSparePart 是来自客户的自动导入的外部表,因此这不是我的责任,我无法更改数据).

I need to find the most robust way to link two tables via nullable foreign-key(modModel and tabSparePart). The only similarity between both is the model's name and the sparepart's description(the tabSparePart is an external table from customer that is imported automatically, so it's not my responsibility and i cannot change the data).

考虑以下备件名称:

W200I_E/Swap
EXCHANGEUNIT P1i / SILVERBLACK/ CYRILLIC

我要查找的型号是 P1iW200I_E.因此,我可以在 where-clause 中确保只有一个强有力的规则:

The modelnames that i want to find are P1i and W200I_E. So there is only one strong rule that i can ensure in the where-clause:

  • 必须有一个分隔符 / 并且相关部分是第一个.
  • there must be a separator / and the relevant part is the first one.

这是示例数据:

Create table #temp(Partname varchar(100))
INSERT INTO #temp
    SELECT 'EXCHANGEUNIT P1i / SILVERBLACK/ CYRILLIC' UNION ALL SELECT 'W200I_E/Swap unit/Black' 

我会完成以下查询:

SELECT RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1)) AS UNIT
FROM #temp
WHERE CHARINDEX('/', Partname) > 0

...返回什么:

EXCHANGEUNIT P1i
W200I_E

但我需要P1i.所以我需要一种方法来处理第一部分由空格分隔的情况.在这种情况下,我需要选择最后一个单词,但前提是它完全分开.

But i need P1i. So i need a way to handle also the case that the first part is separated by whitespaces. In that case i need to select the last word, but only if it is separated at all.

我收到一个 无效的长度参数传递给 LEFT 或 SUBSTRING 函数" - 错误与以下查询:

I'm getting a "invalid length parameter passed to the LEFT or SUBSTRING function"-error with following query:

SELECT REVERSE( LEFT( REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1)))
    , CHARINDEX(' ', REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1))))-1 ))
    AS Unit
FROM #temp
WHERE CHARINDEX('/', Partname) > 0

如果没有第二个没有空格的记录,这将起作用.如果我还要确保第一部分包含空格,我会丢弃有效记录.

This would work without the second record that has no whitespace. If i would also ensure that the first part contains a whitespace, i would discard valid records.

长话短说,我需要根据分隔符的存在找到一种将两种方式结合起来的方法.

To cut a long story short, I need to find a way to combine both ways according to the existence of separators.

PS:这源于:获取 varchar 一部分的最后一个字(左/右)

如果有人感兴趣,这是完整的(工作)存储过程.我确定我从来没有用过这么奇怪的 JOIN:

If anybody is interested, this is the complete (working) stored-procedure. I'm sure i've never used such a strange JOIN:

CREATE PROC [dbo].[UpdateModelSparePart](@updateCount int output)
with execute as Owner
AS
    BEGIN
    BEGIN TRANSACTION

    UPDATE modModel SET fiSparePart=ModelPart.idSparePart
        FROM modModel INNER JOIN 
        (
          SELECT m.idModel
                ,m.ModelName
                ,sp.idSparePart
                ,sp.Price
                ,Row_Number()Over(Partition By idModel ORDER BY Price DESC)as ModelPrice
          FROM modModel AS m INNER JOIN tabSparePart AS sp 
            ON m.ModelName = CASE 
                WHEN CHARINDEX(' ', REVERSE(RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1))))  > 0 THEN
                    REVERSE(  LEFT( REVERSE(RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1)))
                    ,CHARINDEX(' ', REVERSE(RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1))))-1 ))
                ELSE
                    RTRIM(LEFT(sp.SparePartDescription, CHARINDEX('/', sp.SparePartDescription) - 1))
                END
          WHERE (CHARINDEX('/', sp.SparePartDescription) > 0)
          GROUP BY idModel,ModelName,idSparePart,Price
        )As ModelPart
    ON ModelPart.idModel=modModel.idModel
    Where ModelPrice=1

    SET @updateCount = @@ROWCOUNT;

    COMMIT TRANSACTION

END

推荐答案

我解决了这个问题:

SELECT 'Unit' =
    CASE 
    WHEN CHARINDEX(' ', REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1))))  > 0 THEN
         REVERSE( LEFT( REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1)))
        ,CHARINDEX(' ', REVERSE(RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1))))-1 ))
    ELSE 
        RTRIM(LEFT(Partname, CHARINDEX('/', Partname) - 1))
    END
FROM #temp
WHERE CHARINDEX('/', Partname) > 0

丑陋但工作正常.

这篇关于SQL中的三元运算符?“传递给 LEFT 或 SUBSTRING 函数的长度参数无效"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆