C# C类库SQL插入到Select From中
我正在尝试编写一个C类,它允许我在SQL中审计从活动表到审计表的数据。显示对数据所做更改的完整历史记录C# C类库SQL插入到Select From中,c#,sql,sql-server,C#,Sql,Sql Server,我正在尝试编写一个C类,它允许我在SQL中审计从活动表到审计表的数据。显示对数据所做更改的完整历史记录 INSERT INTO tbl_audit SELECT * FROM tbl_data WHERE ID = id 我有一个工作正常如果两个表列在我的类库中匹配正常,我真正需要做的是能够定义列: INSERT INTO tbl_audit (cols) SELECT (vars) FROM tbl_data WHERE ID = id 有人能解释一下我如何循环通过所需变量的每个列吗?有可
INSERT INTO tbl_audit SELECT * FROM tbl_data WHERE ID = id
我有一个工作正常如果两个表列在我的类库中匹配正常,我真正需要做的是能够定义列:
INSERT INTO tbl_audit (cols) SELECT (vars) FROM tbl_data WHERE ID = id
有人能解释一下我如何循环通过所需变量的每个列吗?有可能吗?所以它看起来像:
INSERT INTO tlb_audit (col1, col2, col3) SELECT (col1, col2, col3) FROM tbl_data WHERE ID = id
我的代码看起来像:
class.connection = myconnection.cs
class.currenttable = "tbl_data"
class.newtable = "tbl_audit"
class.col("sqlColumn1_in_tbl_audit")
class.col("sqlColumn1_in_tbl_data")
class.col("sqlColumn2_in_tbl_audit")
class.col("sqlColumn2_in_tbl_data")
etc
class.commit
您可以使用如下脚本获取表列名:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTableName' AND TABLE_SCHEMA='YourSchemaName'
返回结果后,可以循环使用名称来构建插入查询。我不知道这是如何让你在桌面上审计的。我认为您最好使用DBMS构建该功能,或者使用触发器。下面是我在我们的一个应用程序中为已审核表发送电子邮件通知的方法。它从EntityFramework的数据上下文读取实体状态,并将更改格式化为格式化的json字符串
public override int SaveChanges()
{
var auditChanges = ChangeTracker.Entries()
.Where(t => t.State != EntityState.Unchanged && t.Entity.GetType().IsDefined(typeof(AuditAttribute),true))
.Select(t =>
{
var entityType = t.Entity.GetType();
if (entityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies")
{
entityType = entityType.BaseType;
}
return new
{
entityType.Name,
State = t.State.ToString(),
Changes = t.State == EntityState.Deleted ? null : t.CurrentValues.PropertyNames
.Where(pn => t.State == EntityState.Added || t.CurrentValues[pn] == null && t.OriginalValues[pn] != null || t.CurrentValues[pn] != null && !(t.CurrentValues[pn].Equals(t.OriginalValues[pn])))
.ToDictionary(pn => pn, pn => t.CurrentValues[pn]),
Original = t.State == EntityState.Added ? null :
t.OriginalValues.PropertyNames.ToDictionary(pn => pn,
pn => t.OriginalValues[pn])
};
});
if (auditChanges.Any())
{
var auditMessage = new StringBuilder(2048);
var changes = JsonConvert.SerializeObject(auditChanges, Formatting.Indented);
auditMessage.AppendFormat("Timestamp: {0}\r\nUser: {1}\r\nIP Address: {2}\r\n====================\r\n{3}\r\n",
DateTime.Now, HttpContext.Current == null || HttpContext.Current.User == null ? "" : HttpContext.Current.User.Identity.Name,
Controllers.BaseController.GetIpAddress(HttpContext.Current),changes);
NotificationManager.SendNotifications(NotificationType.Audit, this, GetDataSession(),null,auditMessage.ToString());
}
retval = base.SaveChanges();
}
I使用此审核属性标记要审核的类:
public class AuditAttribute : Attribute { }
像这样:
[Audit]
public partial class Agency { }
如果不使用框架,则需要一种识别表行快照前后的方法,以便构建类似的内容。您还可以将审计日志存储到数据库中,或者使用syslog样式的日志api
Sample Audit Table:
Timestamp Date,
EntityName varchar2(50),
Changes varchar2(MAX)?
以下是当有人更改跟踪表时我们收到的示例电子邮件:
The following database changes were made to tracked objects:
Timestamp: 11/13/2015 2:02:34 PM
User:
IP Address: 173.165.34.65
====================
[
{
"Name": "CarrierSetting",
"State": "Modified",
"Changes": {
"DirectBill": true
},
"Original": {
"Id": 531,
"CarrierCode": "MEXIC",
"AllowQuote": true,
"AllowBOL": true,
"DirectBill": false,
"RequireDocusign": false,
}
}
]
这样做的好处是,从理论上讲,您可以通过反序列化Json字符串在更改时重建数据库。您必须执行SQL命令来获取表结构、循环列并构建SQL语句。但是,您希望结构多久改变一次?您已经标记了mysql和sql server,到底是哪一个?很抱歉,无意中勾选了mysql,它的sql server。表结构不会更改。您是否使用任何类型的ORM框架或执行原始sql调用?为什么不在数据库中使用更改数据捕获实现?