我试图弄清楚是否有办法检索在数据库服务器上执行的(完整)sql语句.
我已经发现了一些东西,但它并不是我想要的东西:
IQueryable<SomeType> someQuery = ...
string command = dataContext.GetCommand(query).CommandText;
Run Code Online (Sandbox Code Playgroud)
在我的情况下,这给了我一个命令字符串,如:
SELECT TOP (50) [t0].[ID], ....
FROM [dbo].[someTable] AS [t0]
WHERE ([t0].[someColumn] IS NOT NULL) AND (([t0].[someColumn]) IN (@p0))
Run Code Online (Sandbox Code Playgroud)
在数据库上执行:
exec sp_executesql N'SELECT TOP (50) [t0].[ID], ...
FROM [dbo].[someTable] AS [t0]
WHERE ([t0].[someColumn] IS NOT NULL) AND (([t0].[someColumn]) IN (@p0, @p1))',N'@p0 int,@p1 int',@p0=401,@p1=201
Run Code Online (Sandbox Code Playgroud)
有没有办法从C#代码中检索这个"完整"语句(以及参数值)?
在C#应用程序中,我通过创建带参数的查询字符串来构建查询,然后添加参数及其值的命令.例如:
string query = "UPDATE USERS u SET u.username = @PARM_USERNAME " +
"WHERE u.id = @PARM_USERID ";
command.Parameters.AddWithValue("@PARM_USERNAME", user.username);
command.Parameters.AddWithValue("@PARM_USERID", user.id);
command.Connection.Open();
int res = command.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)
看看带有参数的查询是否有用,这在C#/ Visual Studio中是否可行?我可以查看command.CommandText,但它只显示与上面查询相同的内容,其中包含参数占位符.如果它有帮助,这是针对MySQL的.
我正在使用C#和.NET 3.5.我需要生成并存储一些T-SQL插入语句,稍后将在远程服务器上执行.
例如,我有一个Employees数组:
new Employee[]
{
new Employee { ID = 5, Name = "Frank Grimes" },
new Employee { ID = 6, Name = "Tim O'Reilly" }
}
Run Code Online (Sandbox Code Playgroud)
我需要最终得到一个字符串数组,如下所示:
"INSERT INTO Employees (id, name) VALUES (5, 'Frank Grimes')",
"INSERT INTO Employees (id, name) VALUES (6, 'Tim O''Reilly')"
Run Code Online (Sandbox Code Playgroud)
我正在看一些使用String.Format创建insert语句的代码,但这感觉不对.我考虑使用SqlCommand(希望做这样的事情),但它没有提供将命令文本与参数组合的方法.
仅仅替换单引号并构建字符串就足够了吗?
string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')",
employee.ID,
replaceQuotes(employee.Name)
);
Run Code Online (Sandbox Code Playgroud)
这样做时我应该关注什么?源数据相当安全,但我不想做太多假设.
编辑:只是想指出在这种情况下,我没有SqlConnection或任何方式直接连接到SQL Server.这个特定的应用程序需要生成sql语句并将它们排队等待在其他地方执行 - 否则我将使用SqlCommand.Parameters.AddWithValue()
有没有办法在执行后立即访问CommandText?我有以下代码:
cmd = new OracleCommand(sql.ToString(), conn);
cmd.Parameters.Add(new OracleParameter("@parm", parmValue));
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
Run Code Online (Sandbox Code Playgroud)
我需要知道的是在数据库中执行的sql命令字符串已经包含在sql中的parmValue值.换句话说,我一定不能在查询中看到字符串"@parm",而是查看它的值.
我需要这个,以便我可以将这个sql推送到日志数据库中以供将来参考.
提前致谢.
我的C#代码中有两个SQL语句来检索一些值.我知道他们对SQL注入是开放的,因为我没有使用参数,但我不确定我是否正确实现它们.
(注意:每个都在循环中循环数据表的行)第一个例子:
string sql2 = "select max(day) as day from users u join days d on d.User_ID = u.id where u.ActiveUser = 1 and u.id = " + Users["ID"].ToString();
command.CommandText = sql2;
string dt = command.ExecuteScalar().ToString();
Run Code Online (Sandbox Code Playgroud)
在上面的语句中,它检索日期时间并将其分配给字符串dt.任何带有id或ID的东西都是bigint.
string sql = "SELECT MAX(Day) FROM Days WHERE Project_ID IN (SELECT ID FROM Projects WHERE Parent_ID = -1 AND ID = " + row["ID"] + ") HAVING MAX(Day) < DATEADD(dd, -730, getdate())";
command.CommandText = sql;
object val = command.ExecuteScalar();
Run Code Online (Sandbox Code Playgroud)
上面的语句与第一个语句相同,就像它检索日期时间值一样.任何带有id或ID的东西都是bigint.
这是我第一个想到的,我错过了什么或做错了什么?
string sql2 …Run Code Online (Sandbox Code Playgroud) 我已经阅读过使用正则表达式(在.NET中)匹配字符串内的单词,我可以\b在正则表达式中使用单词boundary specifier().但是,这些调用都不会导致任何匹配
Regex.Match("INSERT INTO TEST(Col1,Col2) VALUES(@p1,@p2)", @"\b@p1\b");
Regex.Match("INSERT INTO TEST(Col1,Col2) VALUES(@p1,@p2)", @"\bINSERT\b");
Run Code Online (Sandbox Code Playgroud)
有什么我做错了吗?
编辑:第二个已经工作;)
从.NET环境中,我可以访问由SqlCommand对象生成的完整SQL字符串吗?
注意:在调试模式下,完整的SQL字符串显示在VisualStudio中的Intellisense悬停中.
如果必须,我愿意使用反射技术.我相信这里有人知道如何做到这一点.
更新1:
我正在调用具有参数的存储过程,cmd.CommandType = CommandType.StoredProcedure并且我正在尝试获取生成并运行的完整SQL.我不知道是不是cmd.如果可能将完整字符串存储在状态字段或类似内容中,则Prepare()方法在这种情况下可能不会有用.
更新2:
根据下面的答案(和引用),表明在准备或执行过程中没有内部生成完整的SQL字符串,我做了一些使用.NET Reflector.即使是内部连接类似乎也会传递对象而不是将它们归结为字符串,例如:
内部抽象void AddPreparedCommand(SqlCommand cmd);
声明类型:System.Data.SqlClient.SqlInternalConnection
程序集:System.Data,Version = 2.0.0.0
总的来说,感谢每个人的细节水平,以证明可以做什么,并展示实际发生的事情.非常感激.我喜欢彻底的解释; 他们增加了保证,并为答案提供了信任.
这是关于具体情况的一些主观问题.这个问题的主要目标是提醒我自己编写解决方案的代码.但是,如果已经有解决方案或替代方法,我想知道它.
我正在开发一个项目,我正在使用Entity Framework 4进行数据库访问.数据库设计是我无法控制的.该数据库是多年前设计的,在我看来,数据库设计不适合当前的数据库目的.这导致非常复杂的查询.
这是我第一次在项目中使用Entity Framework,但我在针对MS SQL Server的开发方面拥有丰富的经验.
我发现自己一次又一次地做的是:
说实话,我开始认为如果你不拥有数据库设计就不应该使用ORM.
除此之外,unescaping sql和替换参数的过程是我想要自动化的过程.我的目标是获得"裸",去参数化的sql,我可以在SSMS中运行.
这是我在配置文件中看到的以及我想要获得的结果的一个非常简单的示例.我的真实情况要复杂很多倍.
捕获:
exec sp_executesql N'SELECT
[Extent1].[ProductName] AS [ProductName]
FROM [dbo].[Products] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
WHERE ([Extent1].[UnitPrice] > @p__linq__0) AND ([Extent2].[CategoryName] = @p__linq__1) AND (N''Chang'' <> [Extent1].[ProductName])',N'@p__linq__0 decimal(1,0),@p__linq__1 nvarchar(4000)',@p__linq__0=1,@p__linq__1=N'Beverages'
Run Code Online (Sandbox Code Playgroud)
期望的结果:
SELECT
[Extent1].[ProductName] AS [ProductName]
FROM [dbo].[Products] AS [Extent1]
INNER JOIN [dbo].[Categories] AS [Extent2] ON [Extent1].[CategoryID] = [Extent2].[CategoryID]
WHERE ([Extent1].[UnitPrice] > …Run Code Online (Sandbox Code Playgroud) 我有 ac# 类,提供一些简单的类和一些基类扩展,比如这个..
public static Boolean ToBooleanOrDefault(this String s, Boolean Default)
{
return ToBooleanOrDefault((Object)s, Default);
}
public static Boolean ToBooleanOrDefault(this Object o, Boolean Default)
{
Boolean ReturnVal = Default;
try
{
if (o != null)
{
switch (o.ToString().ToLower())
{
case "yes":
case "true":
case "ok":
case "y":
ReturnVal = true;
break;
case "no":
case "false":
case "n":
ReturnVal = false;
break;
default:
ReturnVal = Boolean.Parse(o.ToString());
break;
}
}
}
catch
{
}
return ReturnVal;
}
Run Code Online (Sandbox Code Playgroud)
该类编译良好,似乎没有问题。然后我在一个 web 项目中引用了该项目,VS2010 智能感知识别基类扩展,并且 F12/got …
背景:
如果我有以下程序
public class Program
{
public static void Main()
{
using(var connection = new SqlConnection("Server=(local);Database=Testing;Trusted_Connection=True"))
using (var command = connection.CreateCommand())
{
connection.Open();
command.CommandText = "UPDATE Foo set Bar = @Text";
command.Parameters.Add("@Text", SqlDbType.VarChar, 50).Value = "Hello World!";
command.ExecuteNonQuery();
}
}
}
Run Code Online (Sandbox Code Playgroud)
执行时,运行以下查询(根据SQL Server Profiler)
exec sp_executesql N'UPDATE Foo set Bar = @Text',N'@Text varchar(50)',@Text='Hello World!'
Run Code Online (Sandbox Code Playgroud)
我的问题:
我想要做的是,如果我有以下
command.CommandText = "UPDATE Foo set Bar = @Text";
command.Parameters.Add("@Text", SqlDbType.VarChar, 50).Value = "Hello World!";
string query = GenerateQuery(command);
Run Code Online (Sandbox Code Playgroud)
GenerateQuery 会返回字符串
"exec sp_executesql N'UPDATE Foo …Run Code Online (Sandbox Code Playgroud) 我使用C#建立数据库连接,然后使用临时SQL获取数据。这个简单的SQL查询非常易于调试,因为我可以记录SQL查询字符串。如果我使用参数化的SQL查询命令,是否有任何方法可以记录SQL查询字符串以进行调试?
我在基于c#的asp.net页面上有一个SqlCommand对象.SQL和传递的参数在大多数情况下都在工作.我有一个案例不起作用,我收到以下错误:
字符串或二进制数据将被截断.该语句已终止.
我理解错误,但数据库中的所有列都应足够长,以容纳所有发送的内容.
我的问题,
有没有办法看到发送到数据库的实际SQL是从SqlCommand对象?我希望能够在发生错误时通过电子邮件发送SQL.
谢谢,贾斯汀
是否有可能拦截给定SqlCommand将在数据库上执行的查询?
我想跟踪我的Data类调用的所有查询的调试目的,并且找不到一个聪明的方法来执行此操作.
我试图使用一些奇怪的"替换"sql命令字符串,或者附加一个时髦的参数
sb.AppendLine("@" + p.ParameterName + " = " + p.ToDebugString());
Run Code Online (Sandbox Code Playgroud)
("ToDebugString()"是一个扩展方法,它使用或不使用单引号执行"ToString()",具体取决于它是否为字符串)
但这似乎有点不专业,当它遇到一个时它就会失败
SqlDbType.Structured
Run Code Online (Sandbox Code Playgroud)
参数.
或多或少,我想以与SqlServer Profiler在数据库本身内部相同的方式拦截应用程序内部的数据库调用.
先感谢您.
大编辑:
我知道给出一个像这样的简单查询:
SELECT * FROM MyTable WHERE ID=@ID
Run Code Online (Sandbox Code Playgroud)
而不是像这样运行它:
SELECT * FROM MyTable WHERE ID=1234
Run Code Online (Sandbox Code Playgroud)
数据库实际上运行如下过程:
DECLARE @ID int
SET @ID = 1234
SELECT * FROM MyTable WHERE ID=@ID
Run Code Online (Sandbox Code Playgroud)
我可以在应用程序级拦截最后一个块吗?
c# ×11
sql ×6
.net ×4
sql-server ×3
ado.net ×2
sqlcommand ×2
.net-4.5 ×1
asp.net ×1
debugging ×1
linq-to-sql ×1
logging ×1
mysql ×1
reflection ×1
regex ×1
string ×1
types ×1