zoukankan      html  css  js  c++  java
  • 一起谈.NET技术,ASP.NET调用.sql文件(二) 狼人:

      笔者前一阵子发表了一篇《ASP.NET调用.sql文件》文章,主要是是解决数据库配置,减去传统手工附加数据库和自己改写web.config文件等等这些复杂的过程,而是配置的向导。其中给出关键的技术知识点,就是通过sql数据库生成数据库脚本即.sql文件,然后通过调用osql.exe来执行.sql文件。

      这里,园友首先质疑了其安全性,认为程序存在被他人利用的危险。笔者对这方面没有太多经验,希望来位高人讲讲这方面的知识或者演示被利用的过程。所以这块还是一个未知的领域,笔者也不敢保证绝对安全,但是至少目前来没有提出具体的实例来说有危险。

      其次园友提出了本机器上没有数据库的可能性,即程序在一台服务器,数据库在另外一台数据库服务器上,确实如果没有数据库那么上篇文章提到方法就落空了。但是笔者认为这种可能性比较小,因为这种可能性只有说明程序非常大,而且应该是定制软件团队亲自派人过去配置。

      然后笔者在后来调试程序发现,按上篇文章配置数据库发现缺失部分存储过程。笔者的数据库里内容大致分为(数据表,函数,视图,存储过程,数据)这5个部分,由于存储过程很多所以开始没有发现。细致找下原因发现存储过程中部分程序代码里包含中文字符,而调用osql.exe其实就是在cmd控制台里执行,cmd不支持中文,所以造成部分存储过程丢失。期间当然上网查找解决方法,首先想到的是通过来转换编码方式,经过调试发现不能解决。

      所以最后解决方法只有两种:第一将中文字符转换为英文字符,这点不可能。第一中文字符比较多,这里数据与程序对应,这里修改意味着程序里也要对应的修改,工作量比较大。那么第二种就是通过程序来向sql里建立(函数,视图,存储过程)。例如:存储过程是数据库里倒出来的。具体格式为

    USE [magazinedb]
    GO
    /****** Object: StoredProcedure [dbo].[Update_MagazineInformation_HZJ] Script Date: 11/25/2010 10:25:34 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    --更新杂志信息
    create procedure [dbo].[Update_MagazineInformation_HZJ]
    (
    @TabName varchar(20),
    @TypeID decimal,
    @TypeName varchar(20),
    @TypeRemark varchar(100),
    @TypeDate datetime
    )
    as
    begin
    exec('
    update
    '+@TabName+' set [name]='''+@TypeName+''',Remark='''+@TypeRemark+''',Date='''+@TypeDate+'''
    where ID=
    '''+@TypeID+'''
    ')
    end
    GO
    /****** Object: StoredProcedure [dbo].[UP_UserLogin_userPwd_LX] Script Date: 11/25/2010 10:25:34 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROCEDURE [dbo].[UP_UserLogin_userPwd_LX]
    @loginId DECIMAL,
    @oldUserPwd VARCHAR(60),
    @newUserPwd VARCHAR(60),
    @result INT OUTPUT
    AS
    BEGIN
    DECLARE @pwd VARCHAR(60)
    SELECT @pwd = userPwd FROM magazineDB..UserLogin WHERE loginId = @loginId
    IF @pwd <> @oldUserPwd
    SET @result = 0
    ELSE
    BEGIN
    UPDATE magazineDB..UserLogin SET userPwd = @newUserPwd WHERE loginId = @loginId
    SET @result = 1
    END
    END
    GO
    /****** Object: StoredProcedure [dbo].[UP_UserLogin_SeekPwd_GW] Script Date: 11/25/2010 10:25:34 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    create PROCEDURE [dbo].[UP_UserLogin_SeekPwd_GW]
    @loginId DECIMAL,
    @newUserPwd VARCHAR(60)
    AS
    BEGIN
    UPDATE magazineDB..UserLogin SET userPwd = @newUserPwd WHERE loginId = @loginId
    END
    GO
    /****** Object: StoredProcedure [dbo].[UP_user_readState_LX] Script Date: 11/25/2010 10:25:34 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE PROCEDURE [dbo].[UP_user_readState_LX]
    @userID DECIMAL,
    @readState VARCHAR(20)
    AS
    BEGIN
    UPDATE magazineDB..[user] SET readState = @readState WHERE userID = @userID
    END
    GO
    。。。
    。。。

      首先Go是在程序里运行会报错误的,首先需要替换掉,然后运行会报出 Create需要放首行,好多变量未定义的等错误,如果单独执行一个下面的存储过程是没有问题的,但是里面内容有两个就会报错,所以这里想出用编程的方式来一个个读取其中一个存储过程来执行,然后执行下一条

    create procedure [dbo].[Update_MagazineInformation_HZJ]
    (
    @TabName varchar(20),
    @TypeID decimal,
    @TypeName varchar(20),
    @TypeRemark varchar(100),
    @TypeDate datetime
    )
    as
    begin
    exec('
    update
    '+@TabName+' set [name]='''+@TypeName+''',Remark='''+@TypeRemark+''',Date='''+@TypeDate+'''
    where ID=
    '''+@TypeID+'''
    ')
    end

      可以看上面的给出的存储过程实例,观察到 以"Create Proc"的开头和以"/****Object:“结尾中包含一个完整的存储过程。本来笔者开始是以"Create"和"Object"

      但是发现如果存储过程命名包含了以上字符,那么程序就达不到理想的结果了。当然这里要注意注释里不要包含"Create Proc"和"Object:"那么就不会导致提取失败。

    string sr = File.OpenText("存过过程位置");
    StringBuilder ss_sqlcontent
    = new StringBuilder();
    strline
    = string.Empty;
    flag
    = false;

    //这里笔者规定存储过程最后以GO代表结束
    while ((strline = sr.ReadLine()) != "GO")
    {
    if (strline.ToLower().Contains("create proc"))
    {
    flag
    = true;
    ss_sqlcontent.Append(strline);
    ss_sqlcontent.Append(Environment.NewLine);
    //s_sqlcontent.Append(" ");
    }
    else if (flag)
    {
    if (strline.ToLower().Contains("object:"))
    {
    flag
    = false;
    //执行代码
    ExecuteSql(connStr, dbname, ss_sqlcontent.ToString());
    ss_sqlcontent.Clear();
    }
    else
    {
    ss_sqlcontent.Append(strline);
    ss_sqlcontent.Append(Environment.NewLine);
    //s_sqlcontent.Append(" ");
    }
    }
    }
    sr.
    Close();

      上面一段代码就是可以成功将导出的.sql文件成功写入数据库存储过程,那么对应的视图,函数等等都可以观察结构,然后编写对应的结构,由于笔者的函数和视图比较少,所以只用提取"cretae"和"object”之间或者"create"和"Exec"即可。

       那么笔者这个在asp.net中提取.sql文件中内容执行,将内容写入到sql数据库中应该解决上面的所有问题了吧。

       如果疑问欢迎继续探讨

  • 相关阅读:
    Android应用Activity、Dialog、PopWindow、Toast窗口添加机制及源码分析
    Android应用setContentView与LayoutInflater加载解析机制源码分析
    Android图片加载框架Fresco,Glide,Picasso对比分析
    Android加载外部APK资源
    https 真的安全吗,可以抓包吗,如何防止抓包吗
    Android常见的几种内存泄漏
    Android应用结构之LiveData
    Android Jetpack LiveData解析
    android使用socket实现简单的点对点通信
    如何分析解决Android ANR
  • 原文地址:https://www.cnblogs.com/waw/p/2163099.html
Copyright © 2011-2022 走看看