MySQL 过程返回 0 行

标签 mysql sql stored-procedures latitude-longitude

我有一个 MySQL 脚本(使用 Workbench),用于识别位置与一组坐标对的距离。特定半径内的那些位置将被带回,并对这些行进行大量计算。

问题是,当我使用变量而不是在过程中运行查询时,脚本按我的预期工作。当我将其转换为存储过程时,我在没有行中放入的纬度/经度变量并不重要。但是,不会引发任何错误。

我已经选择了在过程中输入的纬度/经度变量,它们看起来与预期一致,即它们具有正确的小数位数。

如果有人能看一下并提出建议,我将不胜感激。谢谢!

两个脚本如下所示。

/*Code run outside of procedure:*/

Set @Radius = 200,
@Latitude = 40.76,
@Longitude = -73.97;

Select
   *
From

          (
        Select
          b.ID,
          b.ContractID,
          b.InsuredName,
          b.UserDefined1,
          b.Line,
          b.Limit,
          b.Excess,
          b.Deductible,
          sum(b.TIV) TIV,
            case 
            when sum(b.TIV) - (b.Excess + b.Deductible) >= b.Limit then (b.Limit * b.Line)
            when sum(b.TIV) - (b.Excess + b.Deductible) < b.Limit and sum(b.TIV) - (b.Excess + b.Deductible) > 0 then (sum(b.TIV) - (b.Excess + b.Deductible)) * b.Line
            when sum(b.TIV) - (b.Excess + b.Deductible) <= 0 then 0 end Exposure$
        From

                (
                Select
                  a.ID,
                  a.ContractID,
                  a.InsuredName,
                  a.UserDefined1,
                  a.Line,
                  a.Limit,
                  a.Excess,
                  a.Deductible,
                  TIV
                From

                      (
                        Select
                            a.ID,
                            a.ContractID,
                            a.InsuredName,
                            a.UserDefined1,
                            a.Line,
                            a.Limit,
                            a.Excess,
                            a.Deductible,
                            TIV,
                            case when cos(radians(l.Latitude))*cos(radians(@Latitude))* cos(radians(@Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(@Latitude)) > 1 
                                then sign(cos(radians(l.Latitude))*cos(radians(@Latitude))* cos(radians(@Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(@Latitude))) 
                                else (6378100 * acos(cos(radians(l.Latitude))*cos(radians(@Latitude))* cos(radians(@Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(@Latitude)))) 
                                end Distance
                        From
                            Location l
                            inner join Account a on a.ID = l.ID
                            )a
                        Where
                          a.Distance <= @Radius

                )b

        Group by
          b.ID,
          b.ContractID,
          b.InsuredName,
          b.UserDefined1,
          b.Line,
          b.Limit,
          b.Excess,
          b.Deductible
        )c
Where
  c.Exposure$ > 0

/*Stored procedure (returning 0 rows):*/

Delimiter //

Create Procedure sp_RingAccounts (in Radius int, in Latitude decimal(9,6), in Longitude decimal(9,6))

Begin

Select Latitude;
Select Longitude;
Select Radius;

Select
   *
From

          (
        Select
          b.ID,
          b.ContractID,
          b.InsuredName,
          b.UserDefined1,
          b.Line,
          b.Limit,
          b.Excess,
          b.Deductible,
          sum(b.TIV) TIV,
            case 
            when sum(b.TIV) - (b.Excess + b.Deductible) >= b.Limit then (b.Limit * b.Line)
            when sum(b.TIV) - (b.Excess + b.Deductible) < b.Limit and sum(b.TIV) - (b.Excess + b.Deductible) > 0 then (sum(b.TIV) - (b.Excess + b.Deductible)) * b.Line
            when sum(b.TIV) - (b.Excess + b.Deductible) <= 0 then 0 end Exposure$
        From

                (
                Select
                  a.ID,
                  a.ContractID,
                  a.InsuredName,
                  a.UserDefined1,
                  a.Line,
                  a.Limit,
                  a.Excess,
                  a.Deductible,
                  TIV
                From

                      (
                        Select
                            a.ID,
                            a.ContractID,
                            a.InsuredName,
                            a.UserDefined1,
                            a.Line,
                            a.Limit,
                            a.Excess,
                            a.Deductible,
                            TIV,
                            case when cos(radians(l.Latitude))*cos(radians(@Latitude))* cos(radians(@Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(@Latitude)) > 1 
                                then sign(cos(radians(l.Latitude))*cos(radians(@Latitude))* cos(radians(@Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(@Latitude))) 
                                else (6378100 * acos(cos(radians(l.Latitude))*cos(radians(@Latitude))* cos(radians(@Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(@Latitude)))) 
                                end Distance
                        From
                            Location l
                            inner join Account a on a.ID = l.ID
                            )a
                        Where
                          a.Distance <= @Radius

                )b

        Group by
          b.ID,
          b.ContractID,
          b.InsuredName,
          b.UserDefined1,
          b.Line,
          b.Limit,
          b.Excess,
          b.Deductible
        )c
Where
  c.Exposure$ > 0 ;

End ;

 //
 Delimiter ;

最佳答案

所以我发现了问题所在,我在过程主体中的变量前面使用了@,而我不需要这样做。

所以当我只需要使用“Latitude”时,我就输入了@Latitude。也许应该更早发现这一点。我认为这样做并没有给我带来错误,这一事实让我感到失望,而且对我所知道的使用 SSMS 的认知存在偏见,这让我将 @ 放在变量前面。

工作脚本现在看起来像:

Delimiter //

Create Procedure sp_RingAccounts (in Radius int, in Latitude decimal(9,6), in Longitude decimal(9,6))

Begin

Select
   *
From

          (
        Select
          b.ID,
          b.ContractID,
          b.InsuredName,
          b.UserDefined1,
          b.Line,
          b.Limit,
          b.Excess,
          b.Deductible,
          sum(b.TIV) TIV,
            case 
            when sum(b.TIV) - (b.Excess + b.Deductible) >= b.Limit then (b.Limit * b.Line)
            when sum(b.TIV) - (b.Excess + b.Deductible) < b.Limit and sum(b.TIV) - (b.Excess + b.Deductible) > 0 then (sum(b.TIV) - (b.Excess + b.Deductible)) * b.Line
            when sum(b.TIV) - (b.Excess + b.Deductible) <= 0 then 0 end Exposure$
        From

                (
                Select
                  a.ID,
                  a.ContractID,
                  a.InsuredName,
                  a.UserDefined1,
                  a.Line,
                  a.Limit,
                  a.Excess,
                  a.Deductible,
                  TIV
                From

                      (
                        Select
                            a.ID,
                            a.ContractID,
                            a.InsuredName,
                            a.UserDefined1,
                            a.Line,
                            a.Limit,
                            a.Excess,
                            a.Deductible,
                            TIV,
                            case when cos(radians(l.Latitude))*cos(radians(Latitude))* cos(radians(Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(Latitude)) > 1 
                                then sign(cos(radians(l.Latitude))*cos(radians(Latitude))* cos(radians(Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(Latitude))) 
                                else (6378100 * acos(cos(radians(l.Latitude))*cos(radians(Latitude))* cos(radians(Longitude)- radians(l.Longitude))+ sin(radians(l.Latitude))* sin(radians(Latitude)))) 
                                end Distance
                        From
                            Location l
                            inner join Account a on a.ID = l.ID
                            )a
                        Where
                          a.Distance <= Radius

                )b

        Group by
          b.ID,
          b.ContractID,
          b.InsuredName,
          b.UserDefined1,
          b.Line,
          b.Limit,
          b.Excess,
          b.Deductible
        )c
Where
  c.Exposure$ > 0 ;

End ;

 //
 Delimiter ;

谢谢, 乔登

关于MySQL 过程返回 0 行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49469783/

相关文章:

Mysql 和 Flyway 命令行 afterMigrate.sql 具有多个文件

mysql - 定位、子串查询

sql - 转换或转换 varchar 行,如 (Mon Jul 18 19 :28:36 EDT 2018) To DateTime

sql - 谁能解释为什么这些查询不一样?

sql - 将包含 View 的代码转换为存储过程

mysql - mysql的存储过程

c# - 通过c#将整数数组传递给oracle过程

mysql - MySQL 中货币的最佳数据类型是什么?

mysql - Galera集群节点不触发wsrep_notify_cmd和wsrep_sst_method

mysql - BigQuery REGEXP_REPLACE