本地调试及服务器需要安装Oracle数据源连接环境才能连接Oracle数据库。
安装配置过程中有很多坑,特记录一下。
Just Do IT
用饼图显示比例数据时,如有较多的项目所占比例较小,默认显示时标识数据堆叠在一起,可以使用此方案。
对数据库定期备份进行检查,并监控容量增长.可以用以下SQL查询并推送消息。
1 2 3 |
select database_name,name,backup_start_date,CAST(backup_size/(1024*1024*1024) AS DEC(28,2))AS [备份大小(GB)],CAST(compressed_backup_size /(1024*1024*1024) AS DEC(28,2)) AS [压缩后(GB)] from msdb..backupset where DATEDIFF(day,backup_start_date,GETDATE())=0 --当天的备份 |
工作中有很多定期执行、定时同步的需求,最适合的方案是SqlServer+Topshelf+Quartznet ,用SqlServer做任务池,用Quartznet做调度计划,用Topshelf将项目部署为系统服务后台运行。
但是整个项目比较庞大,一时半会做不出来。结合手工已经在用的组件,设计了WebApi+SQLServer 的方案。在WebApi里写工作任务,利用SQLServer的维护计划做调度,需要有安装IIS和SQL数据库。
1.首先是写一个可以http调用的api程序。以下程序调用路径是 /api.aspx?act=GO
当然也可以写一个规范的MVC api程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
using System; using System.Reflection; using System.Web.UI; using Newtonsoft.Json; namespace MIS.范例 { public partial class api : Page { private string errcode; private string errmsg; private string info; protected void Page_Load(object sender, EventArgs e) { this.errcode = "0"; this.errmsg = ""; this.info = ""; string act = Request.QueryString["act"]; if (!string.IsNullOrEmpty(act)) { try { //执行act动作 var result = GetType().GetMethod(act, BindingFlags.Instance | BindingFlags.Public).Invoke(this, null) as string; if (!string.IsNullOrEmpty(result)) { Context.Response.ContentType = "text/plain"; Response.Write(result); } } catch (Exception ex) { //错误 Context.Response.ContentType = "text/plain"; Response.Write(JsonConvert.SerializeObject(new { this.errcode, errmsg = ex.ToString(), this.info })); } Response.End(); } } //任务 /act=GO public string GO() { //执行动作 //返回JSON结果 return JsonConvert.SerializeObject(new { this.errcode, this.errmsg, this.info }); } } } |
2. 在SQLServer维护计划里添加T-SQL语句任务,并设置按周期执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
use DATABASE declare @url as Varchar(200) ,@PostData Varchar(10),@ResponseText as Varchar(8000) declare @errcode nvarchar(20),@errmsg nvarchar(2000) set @url='http://10.0.0.1:8080/api?act=GO' exec P_Url_SendRequest @url ,@PostData,@ResponseText OUTPUT select @errcode=StringValue from parsejson(@ResponseText) where NAME='errcode' select @errmsg='考勤同步失败,'+StringValue from parsejson(@ResponseText) where NAME='errmsg' --errcode errmsg info if @errcode<>'0' begin exec P_Send_TextMsg '企业微信消息','wxuser1,wxuser2',@errmsg end |
3. 以上SQL里用到的函数组件
P_Url_SendRequest 连接URL,支持POST\GET 支持返回值
parsejson JSON解析函数
P_Send_TextMsg 企业微信消息推送执行结果
一般使用 dbcc dbreindex(@TABLENAME,”,90) 来重建表索引,但数据库中表较多需要批量全部重建,有的碎片程度不高或数据行数不多,不需要重建时,可以参考使用如下批处理。
程序中执行SQL时,可以使用参数化防注入,如:
1 |
select * from tablenmae where id = @a --@a=123 |
但是where id形式不可以直接使用参数化:
1 |
select * from tablenmae where id in('0,1,2,3') |
1 2 3 |
declare str vchar(100) set str='1,2,3' select * from tablename where id in (select toint from StrTointTable(@str,',') ) |
1 2 3 |
declare str vchar(100) set str='abc,bbb,ccc' select * from tablename where name in (select string from StrToTable(@str,',') |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
IF OBJECT_ID('dbo.StrToTable', 'TF') IS NOT NULL DROP FUNCTION dbo.StrToTable; GO CREATE Function StrToTable(@str nvarchar(2000),@split nvarchar(100)) Returns @tableName Table ( string varchar(50) ) As --该函数用于把一个用逗号分隔的多个数据字符串变成一个表的一列,例如字符串'1,2,3,4,5' 将变成一个表 Begin set @str = @str+@split declare @splen int --分割符长度 set @split=ltrim(rtrim(@split)) set @splen=len(@split) Declare @insertStr nvarchar(50) --截取后的第一个字符串 Declare @newstr nvarchar(2000) --截取第一个字符串后剩余的字符串 set @insertStr = left(@str,charindex(@split,@str)-1) set @newstr = stuff(@str,1,charindex(@split,@str)-1+@splen,'') Insert @tableName Values(@insertStr) while(len(@newstr)>0 and charindex(@split,@newstr)>0) begin set @insertStr = left(@newstr,charindex(@split,@newstr)-1) Insert @tableName Values(@insertStr) set @newstr = stuff(@newstr,1,charindex(@split,@newstr)-1+@splen,'') end if(len(@newstr)>0) begin Insert @tableName Values(@newstr) end delete from @tableName where isnull(string,'')='' Return End |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
IF OBJECT_ID('dbo.StrToIntTable', 'TF') IS NOT NULL DROP FUNCTION dbo.StrToIntTable; GO create Function StrToIntTable(@str nvarchar(2000),@split nvarchar(100)) Returns @tableName Table ( string varchar(50), toint int ) As --该函数用于把一个用逗号分隔的多个数据字符串变成一个表的一列,例如字符串'1,2,3,4,5' 将变成一个表 Begin set @str = @str+@split declare @splen int --分割符长度 set @split=ltrim(rtrim(@split)) set @splen=len(@split) Declare @insertStr nvarchar(50) --截取后的第一个字符串 Declare @newstr nvarchar(2000) --截取第一个字符串后剩余的字符串 set @insertStr = left(@str,charindex(@split,@str)-1) set @newstr = stuff(@str,1,charindex(@split,@str)-1+@splen,'') Insert @tableName Values(@insertStr,null) while(len(@newstr)>0 and charindex(@split,@newstr)>0) begin set @insertStr = left(@newstr,charindex(@split,@newstr)-1) Insert @tableName Values(@insertStr,null) set @newstr = stuff(@newstr,1,charindex(@split,@newstr)-1+@splen,'') end if(len(@newstr)>0) begin Insert @tableName Values(@newstr,null) end update @tableName set toint=cast(string as int) where PATINDEX('%[^0-9]%', string)=0 and PATINDEX('%[0-9]%', string)>0 delete from @tableName where toint is null Return End |
金蝶WISE用户密码使用的是字典加密法,可以在自己开发的MIS系统中批量的更新各账套中的用户密码。
检查发票里的金额税额计算SQL的时候,发现金额、税额四舍五入为2位小数的结果,有的有进位,有的没有进位。
最后检查出其中一个计算变量是float类型,乘了以后再四舍五入必出异常。
两个值求最大最小:
1 2 3 4 |
int a=12; int b=13; int max=Math.Max(a,b);//Math.Max()不能比较datetime int min=a<b?a:b; |
三个值求最大最小:
1 2 3 4 5 |
int a=12; int b=13; int c=14; int max=a>b?(a>c?a:c):(b>c?b:c); int min=a<b?(a<c?a:c):(b<c?b:c); |
多个值求最大最小:
1 2 3 4 5 6 |
int a = 12; int b = 13; int c = 14; int d = 15; int max = new List<int> { a, b, c, d }.Max(); int min = new List<int> { a, b, c, d }.Min(); |
PropertyGrid中如设置datetime类型字段,会自动使用DateTimePicker控件,但此DateTimePicker只能使用默认格式,无法输入时间。
使用PropertyGrid自定格式功能后,使用效果如下:
可以直接输入时间,或者点击下拉三角,调出 DateTimePicker控件选择时间