GVKun编程网logo

asp.net – ExecuteReader需要时间,而不是SQL服务器?(asp.net timer)

10

针对asp.net–ExecuteReader需要时间,而不是SQL服务器?和asp.nettimer这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展ADO.NET2.0中的SqlComma

针对asp.net – ExecuteReader需要时间,而不是SQL服务器?asp.net timer这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展ADO.NET 2.0中的SqlCommand.ExecutePageReader、ADO.Net基础/连接SQLServer/ExecuteNoQuery()/ExecuteScalar、ASP中Server.Execute和Execute实现动态包含(include)脚本的区别、c# – SQL Server将SP_EXECUTESQL识别为对象而不是过程名称等相关知识,希望可以帮助到你。

本文目录一览:

asp.net – ExecuteReader需要时间,而不是SQL服务器?(asp.net timer)

asp.net – ExecuteReader需要时间,而不是SQL服务器?(asp.net timer)

我正在使用ExcuteReader()命令执行存储过程.如果我在sql服务器中执行存储过程,则需要2秒.但代码需要大约2分钟.我试过DataAdapter.Fill().还是一样.

代码有什么问题?

spString = "usp_graph"
        sqlcmd_q.Connection = sqlCnn
        sqlcmd_q.CommandText = spString
        sqlcmd_q.CommandType = CommandType.StoredProcedure
        sqlcmd_q.Parameters.AddWithValue("@clientid",clientId)
        sqlcmd_q.Parameters.AddWithValue("@store",storeID)
        sqlcmd_q.Parameters.AddWithValue("@attributes",attributeNumber)
        sqlcmd_q.Parameters.AddWithValue("@attri1_idx",attribute1_idx)sqlCnn.open()
        sqlcmd_q.CommandTimeout = 300

        sqldr = sqlcmd_q.ExecuteReader() // taking time here
        dt.Load(sqldr)
        dsGrid.Tables.Add(dt)

解决方法

Slow in the Application,Fast in SSMS?.您需要了解的有关此主题的所有信息,等等.

ADO.NET 2.0中的SqlCommand.ExecutePageReader

ADO.NET 2.0中的SqlCommand.ExecutePageReader

http://blog.joycode.com/liuhuimiao/

在.NET 2.0 PDC或Beta1中,可以看到SqlCommand对象新增了个ExecutePageReader方法,该方法实现了分页读取数据的功能。对于分页读取数据,在ADO.NET1.1中(当然2.0也适合)一般常用动态构造SQL语句实现:

    SqlDataReader GetPage(int pageNumber, int pageSize)
    {
       
//pageNumber: 从 0 开始计数的页码
       
//pageSize: 每页的记录数
        String command = String.Format("SELECT * FROM (SELECT TOP {0} * FROM " +
          
"Products ORDER BY ProductID) AS t1 WHERE ProductID NOT IN " +
          
"(SELECT TOP {1} ProductID FROM Products ORDER BY ProductID) ",
           pageSize
* (pageNumber + 1), pageSize * pageNumber);

        SqlConnection conn
= new SqlConnection("server=.;database=Northwind;Trusted_Connection=yes");
        SqlCommand cmd
= new SqlCommand(command, conn);
        conn.Open();
        SqlDataReader dr
= cmd.ExecuteReader(CommandBehavior.CloseConnection);
       
return dr;
    }

        有时为更好实现分页性能效果,也可以采用存储过程建立临时表的方式进行数据分页,但原理基本都差不多。在ADO.NET 2.0 PDC/Beta1中,用SqlCommand.ExecutePageReader进行数据分页:

    SqlDataReader GetPageReader(int pageNumber, int pageSize)
    {
       
int startIndex = (pageNumber - 1) * pageSize;
        String command
= "SELECT * FROM Products";
        SqlConnection conn
= new SqlConnection("server=.;database=Northwind;Trusted_Connection=yes");
        SqlCommand cmd
= new SqlCommand(command, conn);
        conn.Open();
        SqlDataReader dr
= cmd.ExecutePageReader(CommandBehavior.CloseConnection, startIndex, pageSize);

       
return dr;
    }

        最后绑定第2页的5行数据(ProductID从6到10)到GridView1上:

        GridView1.DataSource = GetPage(1, 5);
        GridView1.DataBind();

        从上可以看到,用了ExecutePageReader确实简单了很多。但是,很“不幸”告诉大家,ExecutePageReader在未来版本中将不会出现,也就是说被cut掉了。至于cut的真正原因,还真不知道。不过,我试图用Reflector去看其内部,发现这样一个调用顺序:ExecutePageReader()—》SqlResultSet.CompleteOpenForPageReader()—》SqlResultSet.FetchInternal()—》执行存储过程sp_cursorfetch,也就是实际ExecutePageReader使用了SQLServer的服务器游标进行数据分页读取,但这跟它被cut是否有关?这么好用的一个功能被cut是不是有其他考虑?或许ADO.NET开发小组在鱼和熊掌取舍之间已经做了抉择,只是我还是觉得ExecutePageReader(据说SqlResultSet也被cut,然后连同ExecutePageReader被cut)被cut很可惜。


原文链接: http://blog.csdn.net/21aspnet/article/details/164010

ADO.Net基础/连接SQLServer/ExecuteNoQuery()/ExecuteScalar

ADO.Net基础/连接SQLServer/ExecuteNoQuery()/ExecuteScalar

ADO.Net基础
程序要和数据交互要通过ADO.Net进行,通过ADO.Net就能在程序中执行

sql了。 ADO.Net中提供了对各种不同数据的统一操作接口。
直接在项目中内嵌mdf文件的方式使用sqlServer数据库(基于服务的数据

库)。 mdf文件随着项目走,用起来方便,和在数据库服务上创建数据库

没什么区别,运行的时候会自动附加(Attach)。
双击mdf文件会在“服务器资源管理器”中打开,管理方式和在

Management Studio没有什么本质不同。要拷贝mdf文件需要关闭所有指向

mdf文件的连接。
正式生产运行的时候到附加sqlServer上、修改连接字符串即可,除此之

外没有任何的区别,在“数据库”节点上点右键“附加”;在数据库节点

上任务分离就可以得到可以拷来拷去mdf文件。
用的时候要在控制台、WinForm项目中在Main函数最开始的位置加入备注

中的代码。ASP.Net项目中不需要。

连接sqlServer
连接字符串:程序通过连接字符串指定要连哪台服务器上的、哪个实例的

哪个数据库、用什么用户名密码等。
项目内嵌mdf文件形式的连接字符串“Data Source=.

\sqlEXPRESS;AttachDBFilename=|DataDirectory|

\Database1.mdf;Integrated Security=True;User Instance=True”。
     “.\sqlEXPRESS”表示“本机上的sqlEXPRESS实例”,如果数据库

实例名不是sqlEXPRESS,则需要修改。” Database1.md“f为mdf的文件

名。
ADO.Net中通过sqlConnection类创建到sqlServer的连接,

sqlConnection代表一个数据库连接, ADO.Net中的连接等资源都实现了

Idisposable接口,可以使用using进行资源管理,执行备注中的代码如果

成功了就 ok。


可能遇到的错误
1、由于 启动用户实例的进程时出错,导致无法生成sqlServe的用户实例


http://wenwen.soso.com/z/q15616823.htm
2、版本太低,只支持2005及以下数据库。解决:安装VisualStudio 2008

SP1.
3、启动超时。多试几次

执行简单的Insert语句
sqlCommand表示向服务器 提交的命令(sql语句等)CommandText属性为

要执行的sql语句,Execute NonQuery方法执行一个非查询语句(Update

、Insert、Delete等)
  Using(sqlCommand cmd=conn.CreateCommand())
 {
   cmd.CommandText=“Insert into T_Users(UserName.Password)

values (’admin’,’888888’)”;
   cmd ExecuteNonQuery();
}
ExecuteNonquery返回值是执行的影响行数
常犯错:
string username=‘test’;
…….
cmd.CommandText=“Insert into T_Users(UserName.Password) values

(’username’,’888888’)”;

ExecuteNoQuery()
sqlCommand表示向服务器 提交的命令(sql语句等)CommandText属性为

要执行的sql语句,Execute NonQuery方法执行一个非查询语句(Update

、Insert、Delete等)
  Using(sqlCommand cmd=conn.CreateCommand())
 {
   cmd.CommandText=“Insert into T_Users(UserName.Password)

values (’admin’,’888888’)”;

ExecuteScalar
sqlCommand 的一个方法,用于执行查询,返回查询中返回的结果 集中的

第一行 第一列 。
1)
Output inserted.id
执行有多行结果集的用ExecuteReader();
sqlDataReader
Cmd.executeNoQuery()
Cmd.executeReader()
sqlDataReader reader=cmd.ExecuteReader();
While(reader.Read())
{
Console.writeline(reader.GetString(1));
}
Reader 有方法 GetString,GetInt32等方法,他的参数都是整数,序号

。Getordinal方法,根据列名动态得到序号。
执行有多行结果集的用ExecuteReader();
Reader 有方法 GetString,GetInt32等方法,他的参数都是整数,序号

。Getordinal方法,根据列名动态得到序号。

string source = @"Data Source=.\sqlEXPRESS;AttachDBFilename=|

DataDirectory|\Database1.mdf;Integrated Security=True;User

Instance=True";
            using(sqlConnection conn=new sqlConnection(source) )
            {
                conn.open();

                using (sqlCommand com = conn.CreateCommand())
                {
                   /* com.CommandText = "Insert into T_User

(name,age,nikaname)values('YOYO',20,'PPP')";
                    com.ExecuteNonQuery();
                    Console.WriteLine("插入成功!");
                    */

                    com.CommandText = "select * from T_user";
                    sqlDataReader reader = com.ExecuteReader();
                    while (reader.Read())
                       {
                        string username = reader.GetString

(reader.Getordinal("name"));
                        int age = reader.GetInt32

(reader.Getordinal("age"));
                        Console.WriteLine("Uname={0},Uage=

{1}",username,age);                         }               }            }          Console.WriteLine("打开了!");          Console.ReadKey();         }

ASP中Server.Execute和Execute实现动态包含(include)脚本的区别

ASP中Server.Execute和Execute实现动态包含(include)脚本的区别

最近打算尝试一下在ASP中实现MVC架构,肯定有人问我:ASP都淘汰了,为什么还研究?这点我也知道,自从微软放弃ASP 3.0转向ASP.NET后,ASP已经远远落后于和它几乎同时开始的PHP和JSP,开源比闭源的好处就像PHP和ASP一样,ASP说淘汰就淘汰,谁也救不了,但是值得注意的是ASP在中国市场还是蛮广泛的,尤其是一些中小企业的一些应用,简单的CMS不在话下,而且部署简单,在一些老旧的Windows系统上,不需要安装.NET Framework基本上就可以直接运行了,所以准备一个框架,还是有必要的,不过我这个是实验性框架,只是验证ASP究竟能不能实现类似PHP的MVC架构。
好了,说了这么多,下面直接转入正题吧。这个问题的缘由是因为我需要动态包含ASP文件,大家知道在ASP中只有一种include方法,那就是SSI(Server Side Include),基本上分为以下两种:
复制代码 代码如下:

<!-- #include file="sample.asp" -->
<!-- #include virtual="sample.asp" -->

这两种基本上大家第一种用得多一些,#include virtual包含的是虚拟路径,一般虚拟目录会用得到。但是这两种都属于静态的,如果我们希望是动态包含,但不可以写成:
复制代码 代码如下:

<!-- #include file="<%=MyVar%>" -->
<!-- #include virtual="<%=MyVar%>" -->

上面的写法是错误的,可以理解为,#include指令是在ASP启动脚本引擎执行ASP<% %>标记之间脚本之前执行的,也就是说#include不是ASP的工作,而是服务端程序,如IIS的翻译工作,所以就不会理会你的ASP代码了。
如何实现类似于PHP的include、include_once、require、require_once动态包含脚本方法呢?下面再来看ASP Server对象的一个方法:Server.Execute ,搜索所有的ASP特性,可以发现这个功能最类似于动态include,我们可以做个实验:
Sample.inc.asp
复制代码 代码如下:

<%
Response.Write "Hello World!"
%>

test.asp
复制代码 代码如下:

<%
Server.Execute "Sample.inc.asp"
Response.Write "I am test.asp!"
%>

实际输出应该是“Hello World!I am test.asp!”,说明Server.Execute在动态包含方面可以工作得很好,但是如果我想包含类或者函数呢?接下来做下面这个实验:
Sample.class.asp
复制代码 代码如下:

<%
Class Sample
End Class
%>

test.asp
复制代码 代码如下:

<%
Server.Execute "Sample.class.asp"
Response.Write TypeName(Eval("New Sample"))
%>

直接运行,出现错误“Microsoft VBScript 运行时错误 错误 ''800a01fa'' 类没有被定义: ''Sample''”,结果很令人失望,为什么会出现这种情况呢?查阅了MSDN,找到这段描述:“If a file is included in the calling page by using #include, the executed .asp will not use it. For example, you may have a subroutine in a file that is included in your calling page, but the executed .asp will not recognize the subroutine name. ” 貌似和我遇到的问题有些不一样,难道Server.Execute是代码隔离的?再进行下面这个实验:
Sample.inc.asp
复制代码 代码如下:

<%
Dim MyVar
MyVar = "I am Sample!"
%>

test.asp
复制代码 代码如下:

<%
Dim MyVar
MyVar = "I am test!"
Server.Execute "Sample.inc.asp"
Response.Write MyVar
%>

结果输出的是“I am test!”,很是失望!看来Server.Execute是变量、函数、类这类代码隔离的,也就是说调用端和被调用端在代码级别上互不干扰,看来Server.Execute只能用于包含.asp模板了。
下面隆重出场的是VBScript的脚本特性Execute,传给Execute的必须是有效的VBScript脚本代码,而且Execute是上下文相关的,这点看来很接近于我们需要的动态include。
test.asp
复制代码 代码如下:

<%
Execute "Class Sample : End Class"
Response.Write TypeName(Eval("New Sample"))
%>

上面的代码成功输出我们所需要的类型名称Sample。证明Execute确实可以做到上下文相关,但是问题是利用Execute包含asp文件没有Server.Execute方便,Execute是VBScript脚本自带的,首先只能用来执行代码文本,所以需要读取一次文件内容,其次不能用来识别ASP的一些标签,比如<% %>还有一种类似于<%=MyVar %>的调用方法,所以要过滤掉<% %>,然后要转换<%=MyVar %>为Response.Write MyVar。由于我需要的是包含类文件,不会出现<%=MyVar %>,只要简单的Replace掉<% %>就可以了。关于读取文件内容和简单排除<% %>可以参考下面这个函数:
复制代码 代码如下:

Function file_get_contents(filename)
Dim fso, f
Set fso = Server.CreateObject("Scripting.FilesystemObject")
Set f = fso.OpenTextFile(Server.MapPath(filename), 1)
file_get_contents = f.ReadAll
f.Close
Set f = Nothing
Set fso = Nothing
End Function
Function class_get_contents(filename)
Dim contents
contents = file_get_contents(filename)
contents = Replace(contents, "<" & "%", "")
contents = Replace(contents, "%" & ">", "")
class_get_contents = contents
End Function

有了上面的函数我们可以直接测试下面的代码:
Sample.class.asp
复制代码 代码如下:

<%
Class Sample
End Class
%>

test.asp
复制代码 代码如下:

<%
Execute class_get_contents("Sample.class.asp")
Response.Write TypeName(Eval("New Sample"))
%>

结果输出我们所期望的Sample类型名称,看来Execute还是很强大的,确实很强大,因为经常有不怀好意者用来做“小马”,最简单的ASP一句话木马的写法估计是下面这句了:
复制代码 代码如下:
<%Execute Request("c")%>
比如这段脚本位于file.asp,然后传入file.asp?c=木马文本,呵呵,下面的事你也知道了吧。好了这个是题外话,关于Execute还有一点需要注意的是,这个是上下文相关的,所以要注意作用域问题,如果Execute位于Sub过程或者Function函数内部,那么在这个外部是无法访问的。
参考文档:《Server.Execute Method》 和《使用 Server.Execute 方法》 。
2011年11月23日更新
还有一种VBScript特有的写法叫做ExecuteGlobal,这个可以解决上文说的作用域问题,通过其执行的代码是全局有效的,但是要注意避免类、函数、过程或者变量的重定义覆盖问题。
您可能感兴趣的文章:
  • IIS6 中"ASP 0201 错误 无效的默认脚本语言" 的解决方法
  • 使用ASP控制指定站点解析脚本语言函数
  • 用InstallShield打包ASP程序的脚本
  • asp分页生成html的程序脚本代码
  • 隐藏修改文件时间和文件属性的ASP脚本
  • ASP.NET调用javascript脚本的常见方法小结
  • 从一个网站扒下的asp生成静态页面的代码 特供版
  • iis、apache与nginx禁止目录执行asp、php脚本的实现方法
  • ASP上传漏洞之利用CHR(0)绕过扩展名检测脚本
  • ASP.NET中后台注册js脚本使用的方法对比
  • ASP程序中常用的脚本语言

c# – SQL Server将SP_EXECUTESQL识别为对象而不是过程名称

c# – SQL Server将SP_EXECUTESQL识别为对象而不是过程名称

我使用DBContext. Database.sqlQuery< entity>从我的C#代码库执行存储过程.

它工作正常,但我想知道为什么它正在执行如下的过程:

exec sp_executesql N'EXEC GetCaseList @CaseStage',N'@CaseStage int',@CaseStage=9

而不是

EXEC GetCaseList @CaseStage = 9

有没有什么办法,我的所有程序从这个c#执行
EXEC GetCaseList @CaseStage = 9而不是exec sp_executesql N’EXEC GetCaseList @ CaseStage’,N’@ CaseStage int’,@ CaseStage = 9?

如何使sql Server Profiler将过程名称视为对象而不是SP_EXECUTEsql?

注意:由于我以表格格式通过sql Server Profiler保存跟踪数据,因此我希望以c#为EXEC GetCaseList @CaseStage = 9执行过程.而在ObjectName列中,它将对象作为对象而不是过程名称(GetCaseList)显示为sp_executesql.我只能从c#代码进行更改.

解决方法

问题是,大多数EF执行的数据库调用使用 DbCommandCommadType文本,因此虽然sqlServer识别SP调用,它通过sp_executesql执行它们作为文本.

要获得所需的行为,应按以下方式设置命令:

DbCommand command = ...;
command.CommandText = "StoredProcedureName";
command.CommandType = CommadType.StoredProcedure;

不幸的是,EF不提供指定命令类型的标准方式.我建议的解决方案是基于:

>自定义SP使用CallPrefix StoredProcedureName调用sql语法,以便不会干扰常规调用
> EF命令interception删除前缀,并在执行命令前更改命令类型.

这是实现:

using System.Data;
using System.Data.Common;
using System.Data.Entity.Infrastructure.Interception;

public static class Sp
{
    public const string CallPrefix = "CallSP ";

    public static string Call(string name) { return CallPrefix + name; }

    public class CallInterceptor : DbCommandInterceptor
    {
        public static void Install()
        {
            DbInterception.Remove(Instance);
            DbInterception.Add(Instance);
        }

        public static readonly CallInterceptor Instance = new CallInterceptor();

        private CallInterceptor() { }

        static void Process(DbCommand command)
        {
            if (command.CommandType == CommandType.Text && command.CommandText.StartsWith(Sp.CallPrefix))
            {
                command.CommandText = command.CommandText.Substring(Sp.CallPrefix.Length);
                command.CommandType = CommandType.StoredProcedure;
            }
        }

        public override void ReaderExecuting(DbCommand command,DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            Process(command);
            base.ReaderExecuting(command,interceptionContext);
        }
    }
}

所有你需要的是将上面的类添加到你的项目中,调用Sp.CallInterceptor.Install()一次,例如在你的DbContext静态构造函数中:

public class YourDbContext : DbContext
{
    static YourDbContext()
    {
        Sp.CallInterceptor.Install();
    }
    // ...
}

然后更改您的SP呼叫(使用您的示例):

从:

return DataContext.Database.sqlQuery<CaseList>("EXEC GetCaseList @CaseStage",new sqlParameter("@CaseStage",paramList.CaseStageID)).ToList();

至:

return DataContext.Database.sqlQuery<CaseList>(Sp.Call("GetCaseList"),paramList.CaseStageID)).ToList();

这将生成(对于paramList.CaseStageID == 9):

EXEC GetCaseList @CaseStage = 9

今天关于asp.net – ExecuteReader需要时间,而不是SQL服务器?asp.net timer的分享就到这里,希望大家有所收获,若想了解更多关于ADO.NET 2.0中的SqlCommand.ExecutePageReader、ADO.Net基础/连接SQLServer/ExecuteNoQuery()/ExecuteScalar、ASP中Server.Execute和Execute实现动态包含(include)脚本的区别、c# – SQL Server将SP_EXECUTESQL识别为对象而不是过程名称等相关知识,可以在本站进行查询。

本文标签: