Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如果比例大于2,则显示-1_Sql Server - Fatal编程技术网

Sql server 如果比例大于2,则显示-1

Sql server 如果比例大于2,则显示-1,sql-server,Sql Server,我的表有两个sql\u variant列。在第一列中,插入一个十进制值作为varchar。在第二列中插入一个十进制值作为十进制本身 DECLARE @ATempSelected TABLE(RowNum [int] ,Quantity1 sql_variant, Quantity2 sql_variant) INSERT INTO @ATempSelected SELECT 1, '18.33',18.33 UNION ALL SELECT 2, '18.555555',18.55555

我的表有两个
sql\u variant
列。在第一列中,插入一个十进制值作为varchar。在第二列中插入一个十进制值作为十进制本身

DECLARE  @ATempSelected TABLE(RowNum [int] ,Quantity1 sql_variant,
Quantity2 sql_variant)

INSERT INTO @ATempSelected
SELECT 1,  '18.33',18.33
UNION ALL
SELECT 2,  '18.555555',18.555555
只有当比例小于或等于2时,我才应该将sql_变量转换为十进制结果值。否则我需要在ResultantValue中显示-1。我有以下案例陈述

SELECT T.Quantity1, 
        SQL_VARIANT_PROPERTY(T.Quantity1,'Scale')  ScaleValue1, 
        CASE WHEN SQL_VARIANT_PROPERTY(T.Quantity1,'Scale') <= 2 THEN CONVERT(DECIMAL(8,2),T.Quantity1) ELSE -1 END  AS ResultantValue1,
        T.Quantity2, 
        SQL_VARIANT_PROPERTY(T.Quantity2,'Scale')  ScaleValue2, 
        CASE WHEN SQL_VARIANT_PROPERTY(T.Quantity2,'Scale') <= 2 THEN CONVERT(DECIMAL(8,2),T.Quantity2) ELSE -1 END  AS ResultantValue2
FROM @ATempSelected T
选择T.Quantity1,
SQL变量属性(T.Quantity1,'Scale')ScaleValue1,

SQL_VARIANT_属性(T.Quantity1,'Scale')Quantity1为varchar时的情况,因此默认比例为0>>“所有其他类型”A
varchar
没有比例

对于一般方法,完全使用字符串方法更容易获得刻度长度:

DECLARE  @ATempSelected TABLE(RowNum [int] ,Quantity1 sql_variant,
Quantity2 sql_variant)

INSERT INTO @ATempSelected
SELECT 1,  '18.33',18.33
UNION ALL
SELECT 2,  '18.555555',18.555555;

SELECT T.*
       ,ScaleLength.*
FROM @ATempSelected AS T
CROSS APPLY(SELECT CAST(Quantity1 AS VARCHAR(100)) AS q1
                  ,CAST(Quantity2 AS VARCHAR(100)) AS q2) AS AllText
CROSS APPLY(SELECT LEN(AllText.q1)-CHARINDEX('.',AllText.q1) AS Scale1
                  ,LEN(AllText.q1)-CHARINDEX('.',AllText.q2) AS Scale2 ) AS ScaleLength 

如果字符串值的结尾为零,则可以使用
REVERSE
PATINDEX
从右侧查找除零以外的第一个字符,并将此部分切掉。然后重新反转字符串…

以下是我现在使用的,直到我得到更好的答案

DECLARE  @ATempSelected TABLE(RowNum [int] ,Quantity1 VARCHAR(100), NewQuantity VARCHAR(100))

INSERT INTO @ATempSelected(RowNum,Quantity1)
SELECT 1,  '18.33'
UNION ALL
SELECT 2,  '18.555555'
UNION ALL
SELECT 3,  '18'
UNION ALL
SELECT 4,  '17.'
UNION ALL
SELECT 5,  '16.1'
UNION ALL
SELECT 6,  '1234567.1'
UNION ALL
SELECT 7,  '1234567'
UNION ALL
SELECT 8,  'A'
UNION ALL
SELECT 8,  '1e4'


UPDATE @ATempSelected SET NewQuantity = Quantity1
WHERE ISNUMERIC(Quantity1 + 'e0')  = 1

UPDATE @ATempSelected SET NewQuantity = '-1'
WHERE ISNUMERIC(Quantity1 + 'e0')  = 0


SELECT T.Quantity1,T.NewQuantity,
       --,ScaleLength.*,
       LEN(T.NewQuantity) AS LengthOfString,
       CHARINDEX('.',T.NewQuantity) as IndexVal,
       CASE WHEN  CHARINDEX('.',T.NewQuantity) > 0 THEN LEN(T.NewQuantity)-CHARINDEX('.',T.Quantity1) ELSE 0 END AS Scale,
       CASE WHEN  CHARINDEX('.',T.NewQuantity) > 0 THEN (LEN(T.NewQuantity) - (LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity))-1) ELSE LEN(T.NewQuantity) END AS NumericPart
       ,CASE 
            WHEN CHARINDEX('.',T.NewQuantity) = 0 AND LEN(T.NewQuantity) <= 6 THEN CONVERT(DECIMAL(8,2),T.NewQuantity) --No decimal places
            WHEN CHARINDEX('.',T.NewQuantity) = 0 AND LEN(T.NewQuantity) > 6 THEN -1   --No decimal places; but exceeds the numbers in numeric part
            WHEN LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity) <= 2  
                AND (LEN(T.NewQuantity) - (LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity))-1) <= 6 
                THEN CONVERT(DECIMAL(8,2),T.NewQuantity)  --Decimal places present + Scale is 2 or less + Numeric Part is 6 or less
            ELSE -1
       END AS Result
FROM @ATempSelected AS T
DECLARE@ATempSelected表(RowNum[int],Quantity1 VARCHAR(100),NewQuantity VARCHAR(100))
插入@ATempSelected(RowNum,Quantity1)
选择1,'18.33'
联合所有
选择2,'18.555555'
联合所有
选择3,'18'
联合所有
选择4,'17'
联合所有
选择5,'16.1'
联合所有
选择6,'1234567.1'
联合所有
选择7,‘1234567’
联合所有
选择8,‘A’
联合所有
选择8,‘1e4’
更新@ATempSelected SET NewQuantity=Quantity1
其中ISNUMERIC(Quantity1+'e0')=1
更新@ATempSelected SET NewQuantity='-1'
其中ISNUMERIC(Quantity1+'e0')=0
选择T.Quantity1,T.NewQuantity,
--,缩放长度。*,
LEN(T.NewQuantity)作为长度管柱,
CHARINDEX('.',T.NewQuantity)作为索引,
当CHARINDEX('.',T.NewQuantity)>0时,则LEN(T.NewQuantity)-CHARINDEX('.',T.Quantity1)否则0以刻度结束,
当CHARINDEX('.',T.NewQuantity)>0时,则(LEN(T.NewQuantity)-(LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity))-1)否则LEN(T.NewQuantity)作为数字部分结束
案例
当CHARINDEX('',T.NewQuantity)=0且LEN(T.NewQuantity)为6时,则-1--无小数位数;但超过了数字部分的数字

当LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity)用尾随的零进行测试时?@Shnugo我在看到你的帖子后考虑过这一点,但后来认为18.50的分数是2。也许最好使用一个可选参数来删除尾随的零。@Shnugo添加了删除尾随的零的选项。谢谢你朝着正确的方向轻推。
CREATE FUNCTION [dbo].[udf-Stat-Scale](@Value varchar(50),@Strip0s Bit)
Returns int
Begin
    Declare @Rev varchar(50) = Reverse(@Value)
    Declare @Ret int = IIF(@Strip0s=0, CharIndex('.',@Rev)-1,CharIndex('.',Substring(@Rev, PatIndex('%[^0]%', @Rev+'.'), LEN(@Value)))-1)
    Return IIF(@Ret<0,0,@Ret)
End
Select [dbo].[udf-Stat-Scale](18.250,1)      Returns 2
Select [dbo].[udf-Stat-Scale](18.250,0)      Returns 3
Select [dbo].[udf-Stat-Scale]('18.1234',1)   Returns 4
DECLARE  @ATempSelected TABLE(RowNum [int] ,Quantity1 sql_variant,
Quantity2 sql_variant)

INSERT INTO @ATempSelected
SELECT 1,  '18.33',18.33
UNION ALL
SELECT 2,  '18.555555',18.555555;

SELECT T.*
       ,ScaleLength.*
FROM @ATempSelected AS T
CROSS APPLY(SELECT CAST(Quantity1 AS VARCHAR(100)) AS q1
                  ,CAST(Quantity2 AS VARCHAR(100)) AS q2) AS AllText
CROSS APPLY(SELECT LEN(AllText.q1)-CHARINDEX('.',AllText.q1) AS Scale1
                  ,LEN(AllText.q1)-CHARINDEX('.',AllText.q2) AS Scale2 ) AS ScaleLength 
DECLARE  @ATempSelected TABLE(RowNum [int] ,Quantity1 VARCHAR(100), NewQuantity VARCHAR(100))

INSERT INTO @ATempSelected(RowNum,Quantity1)
SELECT 1,  '18.33'
UNION ALL
SELECT 2,  '18.555555'
UNION ALL
SELECT 3,  '18'
UNION ALL
SELECT 4,  '17.'
UNION ALL
SELECT 5,  '16.1'
UNION ALL
SELECT 6,  '1234567.1'
UNION ALL
SELECT 7,  '1234567'
UNION ALL
SELECT 8,  'A'
UNION ALL
SELECT 8,  '1e4'


UPDATE @ATempSelected SET NewQuantity = Quantity1
WHERE ISNUMERIC(Quantity1 + 'e0')  = 1

UPDATE @ATempSelected SET NewQuantity = '-1'
WHERE ISNUMERIC(Quantity1 + 'e0')  = 0


SELECT T.Quantity1,T.NewQuantity,
       --,ScaleLength.*,
       LEN(T.NewQuantity) AS LengthOfString,
       CHARINDEX('.',T.NewQuantity) as IndexVal,
       CASE WHEN  CHARINDEX('.',T.NewQuantity) > 0 THEN LEN(T.NewQuantity)-CHARINDEX('.',T.Quantity1) ELSE 0 END AS Scale,
       CASE WHEN  CHARINDEX('.',T.NewQuantity) > 0 THEN (LEN(T.NewQuantity) - (LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity))-1) ELSE LEN(T.NewQuantity) END AS NumericPart
       ,CASE 
            WHEN CHARINDEX('.',T.NewQuantity) = 0 AND LEN(T.NewQuantity) <= 6 THEN CONVERT(DECIMAL(8,2),T.NewQuantity) --No decimal places
            WHEN CHARINDEX('.',T.NewQuantity) = 0 AND LEN(T.NewQuantity) > 6 THEN -1   --No decimal places; but exceeds the numbers in numeric part
            WHEN LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity) <= 2  
                AND (LEN(T.NewQuantity) - (LEN(T.NewQuantity)-CHARINDEX('.',T.NewQuantity))-1) <= 6 
                THEN CONVERT(DECIMAL(8,2),T.NewQuantity)  --Decimal places present + Scale is 2 or less + Numeric Part is 6 or less
            ELSE -1
       END AS Result
FROM @ATempSelected AS T