【问题标题】:MySQL to SQL Server SP or Entity FrameworkMySQL 到 SQL Server SP 或实体框架
【发布时间】:2018-03-17 03:44:15
【问题描述】:

我无法将此 MySQL 函数转换为 SQl 服务器,甚至转换为实体框架的 C# 代码。

我将在 GEO Lite 数据库中使用此代码,以便获取 IP 地址上的位置信息。

BEGIN
    DECLARE loc_id INT;

    SELECT geoname_id
    INTO loc_id
    FROM ip_blocks
    WHERE ip_to >= INET_ATON(TRIM(ip))
    ORDER BY ip_to LIMIT 1;

    RETURN IFNULL(loc_id, 0);
END

我尝试创建这个 SQL Server 函数来替换 mysql 函数INET_ATON

CREATE FUNCTION dbo.ipStringToInt (@ip CHAR(15))
RETURNS INT
AS
BEGIN
    DECLARE @rv INT
        ,@o1 INT
        ,@o2 INT
        ,@o3 INT
        ,@o4 INT
        ,@base INT

    SELECT @o1 = CONVERT(INT, PARSENAME(@ip, 4))
        ,@o2 = CONVERT(INT, PARSENAME(@ip, 3))
        ,@o3 = CONVERT(INT, PARSENAME(@ip, 2))
        ,@o4 = CONVERT(INT, PARSENAME(@ip, 1))

    IF (
            @o1 BETWEEN 0
                AND 255
            )
        AND (
            @o2 BETWEEN 0
                AND 255
            )
        AND (
            @o3 BETWEEN 0
                AND 255
            )
        AND (
            @o4 BETWEEN 0
                AND 255
            )
    BEGIN
        SELECT @base = CASE 
                WHEN @o1 < 128
                    THEN (@o1 * 16777216)
                ELSE - (256 - @o1) * 16777216
                END

        SET @rv = @base + (@o2 * 65536) + (@o3 * 256) + (@o4)
    END
    ELSE
        SET @rv = - 1

    RETURN @rv
END
GO

并且还将 MySQL 函数转换为这个版本的 SQL Server:

CREATE FUNCTION IP2Location (@ip VARCHAR(50))
RETURNS INT
AS
BEGIN
    DECLARE @loc_id INT

    SET @loc_id = (
            SELECT geoname_id
            FROM ip_blocks
            WHERE ip_to >= dbo.ipStringToInt(TRIM(@ip))
            ORDER BY ip_to LIMIT 1
            )

    RETURN IFNULL(@loc_id, 0);
END
GO

但是我收到了像 Trim is not recognized built-in function name 这样的错误,这很奇怪。

@loc_id 上出现错误,表示它正在等待(

不胜感激

谢谢

编辑#1: 我的函数现在看起来像这样:

CREATE FUNCTION IP2Location (@ip varchar(50)) RETURNS INTEGER
AS
BEGIN
DECLARE @loc_id INTEGER 

SELECT top 1 geoname_id INTO @loc_id FROM ip_blocks WHERE ip_to >= dbo.ipStringToInt(LTRIM(RTRIM(@ip))) ORDER BY ip_to

RETURN isnull(@loc_id, 0);
END
go

【问题讨论】:

    标签: c# mysql sql-server


    【解决方案1】:

    对于错误:

    Trim 无法识别内置函数名

    TRIM() 仅从 SQL Server 2017 开始可用。

    如果您不使用该版本,请使用LTRIM(RTRIM(@ip))


    对于错误:

    并且在@loc_id 上收到一个错误,表明它正在等待(

    我认为您要查找的不是IFNULL(),而是ISNULL()


    对于错误:

    在函数中无效使用副作用运算符 SELECT

    代替:

    SET @loc_id = (
            SELECT geoname_id
            FROM ip_blocks
            WHERE ip_to >= dbo.ipStringToInt(TRIM(@ip))
            ORDER BY ip_to LIMIT 1
            )
    

    或者:

    SELECT TOP 1 geoname_id
    INTO @loc_id
    FROM ip_blocks
    WHERE ip_to >= dbo.ipStringToInt(LTRIM(RTRIM(@ip)))
    ORDER BY ip_to
    

    改用:

    SET @loc_id = (
            SELECT TOP 1 geoname_id
            FROM ip_blocks
            WHERE ip_to >= dbo.ipStringToInt(LTRIM(RTRIM(@ip)))
            ORDER BY ip_to
            )
    

    【讨论】:

    • 谢谢哥们,我还是得到了Invalid use of a side-effecting operator SELECT within a function,但是其他的错误已经消失了
    • 在这个函数中得到那个错误:IP2Location?
    • 我更新了我的问题以显示我在您修复后拥有的最新版本,我在整个 SELECT 行上都收到了错误
    • :) 我正要建议将 LIMIT 的使用替换为 TOP 1,但你明白了。好的,看看你的编辑
    • 这是您对SELECT INTO @loc_id 的使用。你第一次做对了,只需使用SELECT TOP 1 geoname_id FROM...。像原来一样使用SET
    猜你喜欢
    • 2017-07-07
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2010-10-05
    • 2010-11-04
    • 2011-08-20
    相关资源
    最近更新 更多