union all对于重复的数据也会提取出来
union 不会提取重复的数据
一个sql语句可以有多个union或者union all连接
如果要对连接表中的字段排序,把union的表当成一个子表来操作,如下:
1 2 3 4 |
select ( select id, username from a union select id, qqname as username from b) as datatable order by id |
union all对于重复的数据也会提取出来
union 不会提取重复的数据
一个sql语句可以有多个union或者union all连接
如果要对连接表中的字段排序,把union的表当成一个子表来操作,如下:
1 2 3 4 |
select ( select id, username from a union select id, qqname as username from b) as datatable order by id |
在PAYPAL帐户中添加自己的香港招行“香港一卡通”,需要填写以下信息:
(1)Name on account(帐户名称):收款人名字,英文、中文?
(2) Bank Name(银行名称):填写“CHINA MERCHANTS BANK HONG KONG BRANCH”;
(3) Account Type(帐户类型):选择“Checking(支票收款)”;
(4) Bank Code(银行代码):238,又叫CHATS CODE;
(5) Branch Location(分行地址):21F,12 HARCOURT ROAD CENTRAL
(6) Branch Code(分行代码):填写“860”这三位固定代码(即卡号中间的那三位);
(7) Account Number(帐户号码):填写你自己卡号的最后7位数字(即860之后的7位);
(7) Re-Enter Account Number(重复帐户号码):再次输入上面输入的7位收款帐号。
附截图:
其他信息:
1、招商銀行香港分行SWIFT CODE: CMBCHKHH
2、招商银行卡BIN号
信用卡:431988、356889、439225、439226、439227、518710、518718、622575、622576、622578、479229、479228、552534、552587、622581、622582、622577、521302、628362、356890、370285、370287、370289
借记卡:8位卡、955550、622580、622588、622609、621286、468203、512425、410062、524011、621483、621485、621486、621299
对于一些非多文档类的程序,我们只想让用户打开一个程序的实例,当用户再次点击图标的时候只需将原来运行的程序界面打开即可。那么如何实现这种功能呢?首先,要实现进程的单实例运行,我们可以用互斥对象实现,互斥对象即在系统层上只能创建一个这样标识的对象,当第二个此标识的互斥对象创建时将会返回一个已存在的标志。
单实例运行实现后,我们还要通过消息实现打开前面已经打开的窗口,我们可以用EnumWindows函数来遍例所有窗口以找到已打开窗口的句柄,并通过ShowWindow函数或者自定义消息来激活那个窗口。具体的代码如下:
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
program SingleProc; uses Forms, TlHelp32, Windows, SysUtils, uFmSingleProc in 'uFmSingleProc.pas' {FmSingleProc}; {$R *.res} var HMutex: Hwnd; Ret: Integer; I: integer; // 根据进程ID获取进程名称 function GetProcessNameById(const AID: Integer): String; var h:thandle; f:boolean; lppe:tprocessentry32; begin Result := ''; h := CreateToolhelp32Snapshot(TH32cs_SnapProcess, 0); lppe.dwSize := sizeof(lppe); f := Process32First(h, lppe); while integer(f) <> 0 do begin if Integer(lppe.th32ProcessID) = AID then begin Result:= StrPas(lppe.szExeFile); break; end; f := Process32Next(h, lppe); end; end; function EnumWindowsOpen1stApp(hwnd: HWND; lParam: LPARAM): Boolean ;stdcall; var WindowText : string ; // 窗体标题 procId: Cardinal; wText: array[0..255] of char; begin // 获取进程ID GetWindowThreadProcessId(HWND, procId); if GetProcessNameById(procId) = ExtractFileName(Application.ExeName) then begin GetWindowText(HWND, @wText, 255); if wText = 'Form Title' then begin //ShowWindow有的时候会导致其他的问题,如果ShowWindow有问题可以用下面的发送消息的方法解决 //ShowWindow(hwnd, SW_SHOW); //通过发送消息方式来激活前面的窗口 SendMessage(hwnd, WM_SHOWTHEFORM, 0, 0); end; end; Result := True; end; begin Application.Initialize; Application.MainFormOnTaskbar := True; hMutex := CreateMutex(nil, False, PChar('SingleProcTest')); Ret := GetLastError ; if Ret <> ERROR_ALREADY_EXISTS Then begin Application.CreateForm(TFmSingleProc, FmSingleProc); end else begin // 互斥对象已存在,则遍历查找已打开的程序 EnumWindows(@EnumWindowsOpen1stApp, 0); ReleaseMutex(hMutex); end; Application.Run; 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 41 42 43 |
unit uFmSingleProc; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; const WM_SHOWTHEFORM = WM_USER + 1; type TFmSingleProc = class(TForm) procedure FormCreate(Sender: TObject); private { Private declarations } public // 如果通过ShowWindow函数显示窗口,则不用此消息 procedure WMShowTheForm(Var msg: TMessage); message WM_SHOWTHEFORM; end; var FmSingleProc: TFmSingleProc; implementation {$R *.dfm} { TFmSingleProc } procedure TFmSingleProc.FormCreate(Sender: TObject); begin Self.Caption := 'Form Title'; end; procedure TFmSingleProc.WMShowTheForm(var msg: TMessage); begin Self.WindowState := wsNormal ; Self.Show; Self.BringToFront ; end; end. |
在Delphi7中,使用TAdoQuery读取sybase中的数据,发现在读取numeric字段时,本来存储的是负数值,但tadoquery读出后为正数。
select workdays from workinfo
后来gg了一下,发现这是delphi的一个bug,用Delphi 2010写了一小工具,发现读取不会出现负数为正的情况,说明在后来的delphi版本中修正了此错误。跟踪代码时发现在adodb.pas中的GetFieldData函数中的子函数VarToBuffer中,delphi 2010和delphi 7有所区别,具体代码片断如下:
ftAutoInc, ftInteger:
Integer(Buffer^) := lVal;
将adodb.pas文件拷贝到工程目录下,并将delphi 2010中的此行代码拷贝到这个文件中,发现问题确实解决了,但是修改delphi的源文件还是容易为以后的开发带来隐患,所以还需要其他的办法来解决此问题。
既然是读取numeric字段会报错,那么我们可以想办法把这个字段动态的改变为其他的类型,在sql语句中通过一些数学运算即可改变,最简单的就是跟这个字段除以1(乘以1不会改变),所以最简单的解决办法就是如下更改sql语句:
select workdays / 1 as workdays from workinfo
这样就轻松解决了问题,如果大家遇到类似的问题也可以考虑这种办法来解决问题。
Windows服务作为Windows提供的一种特殊应用程序,拥有下面优点:
1. 随系统启动而启动,不需要用户手动执行,适合做后台检测程序等
2. 不用登录系统即可运行
3. 在后台运行,不与Windows桌面相互影响
4. 拥有System权限,在任务管理器中无法结束运行
Windows不建议在服务程序中与桌面有交互,在Windows Xp及以前的版本Windows服务和用户桌面还运行在一个session下,所以服务程序还可以比较轻松的与桌面进行交互。但是自Windows Vista及以后的系统中,服务程序是运行于session0中,而第一个启动的用户则运行于session1中,要想在服务中显示桌面或者与桌面程序交互要使用很复杂的技术,甚至用CreateProcess和ShellExecute启动的应用程序都无法在用户桌面中显示。
一、在Delphi中创建Windows服务程序
Delphi中提供了创建Windows服务的程序框架,生成Windows服务工程的具体方法如下,点击菜单File->New->Other,在里面寻找Service Application项目,点击OK按钮生成即可。这里会生成一个带界面的TService1类。选中TService1界面,下面介绍一下TService的相关属性和事件。
TService属性:
TService事件:
1. procedure TService1.ServiceStart(Sender: TService; var Started: Boolean);
在该服务启动的时候调用OnStart事件,参数Started的默认为True,所以不用在该事件中再设置Started := True; 在此事件中如果判断某些条件不允许服务运行,则可以将Started置为False,这样服务将会不再启动。
2. procedure TService1.ServiceStop(Sender: TService; var Stopped: Boolean);
在该服务被停止的时候调用OnStop事件,Stopped的默认为True,在此事件中如果判断某些条件不允许服务停止则可将Stopped置为False来防止服务被停止。
3. procedure TService1.ServiceExecute(Sender: TService);
服务的主体执行部分,需要将服务的主要功能实现代码放在此事件中,此过程执行完毕后服务将会自动停止,所以一般在此事件中要写类似如下代码:
1 2 3 4 5 6 7 8 |
procedure TService1.ServiceExecute(Sender: TService); begin while not Terminated do begin Sleep(10); ServiceThread.ProcessRequests(False); end; end; |
4.procedure TService1.ServicePause(Sender: TService; var Paused: Boolean);
在服务被暂停时调用的事件,Paused的含义类似ServiceStart事件中的Started.
5. procedure TService1.ServiceContinue(Sender: TService; var Continued: Boolean);
服务被暂停后重新启动继续执行时调用的事件,Continued的含义类似ServiceStart事件中的Started
经过简单的点击后,一个最基本的Windows服务程序已经编写完成了,编译工程,将会生成一个exe程序,本例中生成一个ServiceTest.exe。
打开命令行窗口,将目录定位到工程的输出目录,输入ServiceTest.exe /install并执行,刚才编写的服务就安装到系统中了。
卸载服务时使用ServiceTest.exe /unstall
可以在命令行后面加/silent参数,使其不弹出安装、卸载成功的提示框。
注意:使用/install这种方式安装时,服务的名字是服务窗口的类名,不是DisplayName,服务管理器中显示的是DisplayName
也可使用Windows自带的sc命令来创建或者删除服务,创建的示例代码如下:
1 2 |
sc create "ServiceName" binpath= "C:UsersAdministratorDesktopServiceTestServiceTest.exe" sc delete ServiceName |
二、一些很有用的管理服务的函数
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
unit ServiceMgr; interface uses Windows,Messages,SysUtils,Winsvc,Dialogs; function StartServices(Const SvrName:String):Boolean; function StopServices(Const SvrName:String):Boolean; function QueryServiceStatu(Const SvrName: String):String; function CreateServices(Const SvrName,FilePath:String):Boolean; function DeleteServices(Const SvrName: String):Boolean; function IsServiceExisted(Const SvrName: String):Boolean; implementation //开启服务 function StartServices(Const SvrName: String): Boolean; var sMgr, sHandle:SC_HANDLE; c:PChar; begin Result:=False; sMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if sMgr <=0 then Exit; sHandle := OpenService(sMgr, PChar(SvrName), SERVICE_ALL_ACCESS); if sHandle <=0 then Exit; try Result:=StartService(sHandle, 0, c); CloseServiceHandle(sHandle); CloseServiceHandle(sMgr); except CloseServiceHandle(sHandle); CloseServiceHandle(sMgr); end; end; //停止服务 function StopServices(Const SvrName: String): Boolean; var sMgr, sHandle: SC_HANDLE; d: TServiceStatus; begin Result := False; sMgr := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS); if sMgr <=0 then Exit; sHandle := OpenService(sMgr,PChar(SvrName),SERVICE_ALL_ACCESS); if sHandle <=0 then Exit; try Result:=ControlService(sHandle, SERVICE_CONTROL_STOP,d); CloseServiceHandle(sMgr); CloseServiceHandle(sHandle); except CloseServiceHandle(sMgr); CloseServiceHandle(sHandle); end; end; //查询当前服务的状态 function QueryServiceStatu(Const SvrName: String): String; var sMgr, sHandle: SC_HANDLE; d: TServiceStatus; begin Result := '未安装'; sMgr := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS); if sMgr <=0 then Exit; sHandle := OpenService(sMgr,PChar(SvrName),SERVICE_ALL_ACCESS); if sHandle <= 0 then Exit; try QueryServiceStatus(sHandle, d); if d.dwCurrentState = SERVICE_RUNNING then Result := '启动' //Run else if d.dwCurrentState = SERVICE_RUNNING then Result := 'Wait' //Runing else if d.dwCurrentState = SERVICE_START_PENDING then Result := 'Wait' //Pause else if d.dwCurrentState = SERVICE_STOP_PENDING then Result := '停止' //Pause else if d.dwCurrentState = SERVICE_PAUSED then Result := '暂停' //Pause else if d.dwCurrentState = SERVICE_STOPPED then Result := '停止' //Stop else if d.dwCurrentState = SERVICE_CONTINUE_PENDING then Result := 'Wait' //Pause else if d.dwCurrentState = SERVICE_PAUSE_PENDING then Result := 'Wait'; //Pause CloseServiceHandle(sMgr); CloseServiceHandle(sHandle); except CloseServiceHandle(sMgr); CloseServiceHandle(sHandle); end; end; {建立服务} function CreateServices(Const SvrName,FilePath: String): Boolean; var sMgr, sHandle:SC_HANDLE; begin Result:=False; if FilePath = '' then Exit; sMgr := OpenSCManager(nil,nil,SC_MANAGER_CREATE_SERVICE); if sMgr <= 0 then Exit; try sHandle := CreateService(sMgr, PChar(SvrName), PChar(SvrName), SERVICE_ALL_ACCESS, SERVICE_INTERACTIVE_PROCESS or SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,SERVICE_ERROR_NORMAL, PChar(FilePath),nil,nil,nil,nil,nil); if sHandle <= 0 then begin ShowMessage( SysErrorMessage(GetlastError)); Exit; end; CloseServiceHandle(sMgr); CloseServiceHandle(sHandle); Result := True; except CloseServiceHandle(sMgr); CloseServiceHandle(sHandle); Exit; end; end; {卸载服务} function DeleteServices(Const SvrName: String): Boolean; var sMgr, sHandle:SC_HANDLE; begin Result:=False; sMgr := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS); if sMgr <= 0 then Exit; sHandle :=OpenService(sMgr,PChar(SvrName),STANDARD_RIGHTS_REQUIRED); if sHandle <= 0 then Exit; try Result := DeleteService(sHandle); if not Result then ShowMessage(SysErrorMessage(GetlastError)); CloseServiceHandle(sHandle); CloseServiceHandle(sMgr); except CloseServiceHandle(sHandle); CloseServiceHandle(sMgr); Exit; end; end; function IsServiceExisted(Const SvrName: String):Boolean; var sMgr, sHandle:SC_HANDLE; begin Result:=False; sMgr := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS); if sMgr <= 0 then Exit; sHandle :=OpenService(sMgr, PChar(SvrName), STANDARD_RIGHTS_REQUIRED); if sHandle > 0 then Result := True; end; end. |
调用方法:
{启动服务} StartServices(服务名);
{停止服务} StopServices(服务名);
{新建服务} CreateServices(服务名,exe文件路径);
{删除服务} DeleteServices(服务名);
{获取服务状态} string:=QueryServiceStatu(服务名);
注意这里的服务名是Service类的名称,不是DisplayName
三、Delphi中编写Windows服务的注意事项
1. 尽量避免使用ShowMessage等直接进行调试,容易造成服务无法响应等问题。
2. 停止服务时提示”Windows无法停止 xxx 服务(位于 本地计算机 上)” ,则可能是OnStop事件结束时将Stopped设置成了False或者OnExecute事件不能结束或者OnExecute与界面进行了不正确的交互。
3. Windows Vista及上版本的系统中不再支持服务中显示窗口,所以在这些版本的系统上,如果需要显示窗口,则要另外创建一个窗口程序,并与之用消息通讯以显示窗口。
四、一些有用的链接
Subverting Vista UAC in Both 32 and 64 bit Architectures
http://www.codeproject.com/Articles/35773/Subverting-Vista-UAC-in-Both-and-bit-Archite
如何在Windows Service里面运行程序
http://blog.sina.com.cn/s/blog_5f8817250100vooy.html
当我们需要响应鼠标滚轮效果的时候,我们需要在Form的FormMouseWheel、FormMouseWheelDown、FormMouseWheelUp事件中进行处理。如下面的代码:
1 2 3 4 5 6 7 8 9 10 11 |
procedure TForm1.FormMouseWheelDown(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin Edit1.Top := Edit1.Top + 10; end; procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin Edit1.Top := Edit1.Top - 10; end; |
但是在实际运行中我们发现,每次滚轮后Edit1的顶部位置往上或下移动了两次,这是因为TControl的DoMouseWheel调用了该事件,如果该事件中Handled返回值为true,则DoMouseWheel将认为该事件处理完毕,不在执行后边的代码,如果返回false则继续执行后面的代码。
所以如果要避免这几个事件执行多次,在执行完你要执行的操作后,返回Handled := True;即可。如下:
1 2 3 4 5 6 |
procedure TForm1.FormMouseWheelUp(Sender: TObject; Shift: TShiftState; MousePos: TPoint; var Handled: Boolean); begin Edit1.Top := Edit1.Top - 10; Handled := True; end; |
DoMouseWheel的代码如下:
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 |
function TControl.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; var IsNeg: Boolean; begin Result := False; if Assigned(FOnMouseWheel) then FOnMouseWheel(Self, Shift, WheelDelta, MousePos, Result); if not Result then begin Inc(FWheelAccumulator, WheelDelta); while Abs(FWheelAccumulator) >= WHEEL_DELTA do begin IsNeg := FWheelAccumulator < 0; FWheelAccumulator := Abs(FWheelAccumulator) - WHEEL_DELTA; if IsNeg then begin if FWheelAccumulator <> 0 then FWheelAccumulator := -FWheelAccumulator; Result := DoMouseWheelDown(Shift, MousePos); end else Result := DoMouseWheelUp(Shift, MousePos); end; end; end; |
使用javac命令来编译java文件生成.class文件
使用java命令+类名来运行编译好的class文件
假设HelloJava.java代码文件如下
1 2 3 4 5 6 7 8 9 |
public class HelloJava { public HelloJava() { System.out.print("Hello Java!"); } public static void main(String args[]) { HelloJava hellojava = new HelloJava(); } } |
在命令行工具中,cd到HelloJava.java文件所在的目录
运行如下命令:
1 |
javac ./HelloJava.java |
运行完毕后,在目录中会出现HelloJava.class文件
然后使用java命令运行这个类:
1 |
java HelloJava |
此处需要注意的是:
假在com/bcoder/目录下有HelloPackageJava.java文件,文件内容如下:
1 2 3 4 5 6 7 8 9 10 11 |
package com.bcoder; public class HelloPackageJava { public HelloPackageJava() { System.out.print("Java in package!"); } public static void main(String args[]) { HelloPackageJava pkgJava = new HelloPackageJava(); } } |
如需编译HelloPackageJava.java,则cd到com目录的上一层目录,然后执行如下命令:
1 |
javac .\com\bcoder\HelloPackageJava.java |
编译完后使用如下命令运行
1 |
java com.bcoder.HelloPackageJava |
如果在HelloPackageJava.java目录下编译然后运行java HelloPackageJava会报“错误: 找不到或无法加载主类 HelloPackageJava”
1. 整型数据类型中,需要内存空间最少的是(D)
A) short B) long C) int D) byte
关于这个问题,我认为byte应该是字节型,就不算整型,怎么能选D呢。
2. Java中的default关键字 default关键字是Java8 的新特性,其作用是使用此关键字可以在接口中给接口函数增加默认的实现内容,以方便接口增加新的接口函数后继承自该接口的类也可以编译通过。如下代码:
1 2 3 4 5 6 |
public interface MyInterfact{ public void func1(); default public void func2(){ System.out.println("This is func2"); } } |
3. Java中的native关键字 native用于定义本地方法,即方法的定义是在java中定义,但是其实现是用非java语言实现的
4. Java中的多态性——重载,重载函数不能同时有完全相同的参数(即参数数量和参数数据类型都一致),参数的数量可以与原来的不同,返回值也可以与原来的不同。
5. 子类覆盖父类方法时(注意:是覆盖不是重载),方法的作用域不能低于父类方法的作用域,比如父类用public声明的,子类中就不可以用private或者default声明,另附几个作用域关键字对应的作用范围
|
|
|
|
外部包 |
public |
|
|
|
|
protected | |
|
|
|
default |
|
|
|
|
|
|
|
|
|
6. 一个.java文件中,可以有多个类,但是只能有一个使用public定义的类
7. throw是在一个过程中抛出具体的某个异常(异常类的实例);throws是定义在方法头的可能会抛出的异常,可以同时定义多个异常类。
8. 参与运算时,数据类型会从低精度的数据类型向高精度自动转换
1 2 3 |
int x = 4; System.out.println("value is: " + (x>4?99:9)); //输出结果为:value is: 9 |
改变一下:
1 2 3 |
int x = 4; System.out.println("value is: " + (x>4?99.0:9)); //输出结果为value is: 9.0 |
9. Java中基本数据类型包括byte、int、char、long、float、double、boolean和short
引用数据类型包括:类,数组,接口等(简单来说就是除了基本数据类型之外的所有类型),所以String也是引用类型的
10. Java中抽象类可以有实现方法,但是抽象类不能实例化,所以也无法调用实现方法,其他抽象类的特点
a. 抽象方法 abstract void f(); 抽象方法不能包含有任何方法的BODY 。
b. 如果一个类包含1个或者多个抽象方法, 则该类必须限定为抽象的。
需要在前面指定 abstract 关键字。
(1)抽象类不能被实例化
(2)包含抽象方法的类,必须标识 abstract
c. 如果从一个抽象类继承, 必须对所有抽象方法进行覆盖 , 否则导出类也是抽象的
d. 也可以考虑创建没有任何抽象方法的抽象类 。
11. 如果子类中没有显式调用父类的某个形式的构造函数,子类的构造函数会自动调用父类的无参数的构造函数,不管何种情况基类的无参构造函数肯定会被调用。