Sql server 如何将int SQL Server中的结果转换为字符串

Sql server 如何将int SQL Server中的结果转换为字符串,sql-server,Sql Server,SQL代码: ALTER PROCEDURE [dbo].[psGetReprintNLot] @codOrder VARCHAR(15) AS BEGIN SET NOCOUNT ON; SELECT DISTINCT codPackedBatch AS codPackedBatch FROM PackedOrder INNER JOIN [Order] ON Packe

SQL代码:

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT 
        codPackedBatch AS codPackedBatch
    FROM            
        PackedOrder 
    INNER JOIN
        [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE
        (PackedOrder.codOrder = @codOrder OR @codOrder IS NULL)
        AND RIGHT([PackedOrder].codPackedBatch, 1) <> 8 
    ORDER BY
        codPackedBatch ASC

    IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END
当我尝试执行存储过程时,出现以下错误:

Msg 245,16级,状态1,程序psGetReprintNLot,第47行
将varchar值“M18111301”转换为数据类型int时,转换失败

但当我试图执行时:

Exec [psGetReprintNLot] '721718346' 
它按预期工作。如果输入字符串,如何获取值

如果我像下面这样尝试:我得到的是“M”的正确结果,但不是正常的“72…46”

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;
    --SELECT DISTINCT codPackedBatch as codPackedBatch
    --FROM PackedOrder 
    --INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    --WHERE (PackedOrder.codOrder = @codOrder or @codOrder IS NULL)
    --AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc                    
    SELECT DISTINCT codPackedBatch AS codPackedBatch
    FROM PackedOrder 
    WHERE (PackedOrder.codPackedOrder = @codOrder OR @codOrder IS NULL) 
      AND RIGHT([PackedOrder].codPackedBatch, 1) <> 8 
    ORDER BY codPackedBatch ASC

    IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END
ALTER过程[dbo].[psgetreportnlot]
@CODCORDER VARCHAR(15)
作为
开始
不计数;
--选择DISTINCT codPackedBatch作为codPackedBatch
--来自PackedOrder
--PackedOrder.codOrder=[Order].codOrder上的内部联接[Order]
--其中(PackedOrder.codOrder=@codOrder或@codOrder为空)
--右([PackedOrder].codPackedBatch,1)8按codPackedBatch Asc订购
选择DISTINCT codPackedBatch作为codPackedBatch
来自PackedOrder
其中(PackedOrder.codPackedOrder=@codOrder或@codOrder为空)
右([PackedOrder].codPackedBatch,1)8
按codPackedBatch ASC订购
如果@错误0
返回-1
其他的
返回0
抵消
结束

出现问题的原因是您的
PackedOrder.codOrder
列有一个INT数据类型,您正在将其与varchar进行比较:

PackedOrder.codOrder = @codOrder
当字符串@codOrder仅包含数字时,SQLServer将成功地将@codOrder的内容转换为INT,然后运行查询

当@codOrder也包含alpha字符时,SQLServer将无法将其转换为int并给出此错误

SQLServer不会尝试将所有表数据转换为varchar以执行string:string比较,因为隐式转换表数据以匹配这样的变量会浪费资源,并且在大多数情况下,数据转换意味着无法使用索引。总之,这意味着将数百万行转换为与一个变量的数据类型匹配会带来糟糕的性能影响,因此不应该这样做

如果您真的想显式地进行转换,您可以将表列强制转换为varchar,但请参见inf,因为表列是INT,所以无论如何它都不会包含
M18111301
,因此将一百万INT转换为varchar,然后在其中搜索字母数字是一个100%无意义的练习

您最好更改您的过程,这样它就可以改为使用INT类型的@codOrder,并停止尝试向其中输入字母数字数据

或者,根据问题下的注释,如果
M18111301
在某种程度上与表中的数据相关(例如,表中确实包含
18111301
,因此您应该切掉M),则修改变量,使其与表中的某个内容匹配,然后执行搜索


回应您的编辑和我的评论如下:

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

  IF @codOrder LIKE 'M%'
    SELECT DISTINCT codPackedBatch AS codPackedBatch
    FROM PackedOrder 
    WHERE (PackedOrder.codPackedOrder = @codOrder OR @codOrder IS NULL) 
      AND RIGHT([PackedOrder].codPackedBatch, 1) <> 8 
    ORDER BY codPackedBatch ASC
  ELSE
    SELECT DISTINCT codPackedBatch as codPackedBatch
    FROM PackedOrder 
    INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE (PackedOrder.codOrder = @codOrder or @codOrder IS NULL)
    AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc     
  END IF;

    IF @@Error <> 0 
        RETURN -1;
    ELSE
        RETURN 0;

    SET NOCOUNT OFF;
END
ALTER过程[dbo].[psgetreportnlot]
@CODCORDER VARCHAR(15)
作为
开始
不计数;
如果@codOrder像'M%'
选择DISTINCT codPackedBatch作为codPackedBatch
来自PackedOrder
其中(PackedOrder.codPackedOrder=@codOrder或@codOrder为空)
右([PackedOrder].codPackedBatch,1)8
按codPackedBatch ASC订购
其他的
选择DISTINCT codPackedBatch作为codPackedBatch
来自PackedOrder
PackedOrder.codOrder=[Order].codOrder上的内部联接[Order]
其中(PackedOrder.codOrder=@codOrder或@codOrder为空)
右([PackedOrder].codPackedBatch,1)8按codPackedBatch Asc订购
如果结束;
如果@错误0
返回-1;
其他的
返回0;
不计数;
结束
?


如果您希望@codOrder值在其他任何地方都有任何alpha字符,如
123TP456
,那么您可以使用
如“%[A-Z]%”进行测试。

可能您正在寻找此值

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT codPackedBatch as codPackedBatch
    FROM PackedOrder 
    INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE (@codOrder IS NULL or @codOrder = case when isnumeric(@codOrder) then PackedOrder.codOrder else PackedOrder.codPackedOrder end)
    AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc      

   IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END
ALTER过程[dbo].[psgetreportnlot]
@CODCORDER VARCHAR(15)
作为
开始
不计数;
选择DISTINCT codPackedBatch作为codPackedBatch
来自PackedOrder
PackedOrder.codOrder=[Order].codOrder上的内部联接[Order]
其中(@codOrder为NULL或@codOrder=case当为数字(@codOrder)时,则为PackedOrder.codOrder else PackedOrder.codPackedOrder end)
右([PackedOrder].codPackedBatch,1)8按codPackedBatch Asc订购
如果@错误0
返回-1
其他的
返回0
抵消
结束

@codOrder以字母M开头;您希望如何将其转换为INT?放下它?将其更改为13(这是字母表中的第13个字母),将其更改为77(它是M的ascii码)?什么?您必须决定如何使用非数字字符;数据库无法为您决定!尝试执行:exec[psGetReprintNLot]“M18111301”而不是exec[psGetReprintNLot]“721718346”。您可能无法按预期工作。@BishalGautam很好……表“订单”/“打包订单”中的“codOrder”列可能是int类型。是的,您的理解是正确的。但是我需要一些结果,它们以codOrder或Codpackedorder的形式出现。所以我需要“M”。如果我这样尝试:那么,你的意思是:如果你传递的@codOrder在开头有一个M,那么它是一个
PackedOrder.codPackedOrder
,如果输入在开头没有M,那么它是一个
PackedOrder.codOrder
?那么为什么不使用IF呢
如果@codOrder类似于'M%',则(运行一个查询)其他(运行另一个查询)结束
ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT codPackedBatch as codPackedBatch
    FROM PackedOrder 
    INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE (@codOrder IS NULL or @codOrder = case when isnumeric(@codOrder) then PackedOrder.codOrder else PackedOrder.codPackedOrder end)
    AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc      

   IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END