请问有人知道如何用Delphi实现控制ODBC中的项目的增加与修改吗?

jilimi 2000-03-03 10:20:00
请问有人知道如何用Delphi实现控制ODBC中的项目的增加与修改吗?比如,我要在ODBC的系统DSN页中增加或修改一个Sql Server的DSN,应该如何做呢?
...全文
195 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Un1 2000-03-03
  • 打赏
  • 举报
回复
If you're developing a VB database application, you're probably using a DSN (data source name) because it makes the access to your database file easier. Of course, when you distribuite your application, you must create the DSN.

There are some installation programs that offers the possibility to create the DSN during the setup process, but unfortunately the Setup Wizard distributed with VB5 or earlier versions, or the Package and Deployment Wizard that comes with VB6 doesn't offer this option. Therefore you must create the DSN manually.

This doesn't have to be hard, though, and can be done programmatically, for example the first time you run your app. The SQLConfigDataSource ODBC API function is what you need, in that it allows you to create, modify or delete a DSN:

Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" (ByVal _
hwndParent As Long, ByVal fRequest As Long, ByVal lpszDriver As String, _
ByVal lpszAttributes As String) As Long

The first argument is the parent window's handle, and can be null (0& in VB). The second argument specifies the action to be performed: 1 to add, 2 to config and 3 to delete a DSN. The third argument is a string that specifies the driver to use: for example, to create a DSN from an Access database you must pass "Microsoft Access Driver (*.mdb)". The last parameter is a string that contains many information about the DSN, such as the DSN name, the source database file, the user name and the password (if any).
Here is function that makes easier the process to create or delete a DSN:


' Registry API functions
Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" (ByVal _
hwndParent As Long, ByVal fRequest As Long, ByVal lpszDriver As String, _
ByVal lpszAttributes As String) As Long
Private Declare Function RegCloseKey Lib "advapi32" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
(ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
ByVal samDesired As Long, ByRef phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32" Alias _
"RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _
ByVal lpReserved As Long, ByRef lpType As Long, ByVal lpData As String, _
ByRef lpcbData As Long) As Long

Const REG_SZ = 1
Const KEY_ALL_ACCESS = &H2003F
Const HKEY_CURRENT_USER = &H80000001

Public Const ODBC_ADD_DSN = 1 ' Add data source
Public Const ODBC_REMOVE_DSN = 3 ' Delete data source

Sub MakeDSN(ByVal sDSN As String, ByVal sDriver As String, _
ByVal sDBFile As String, ByVal lAction As Long)

Dim sAttributes As String
Dim sDBQ As String
Dim lngRet As Long

Dim hKey As Long
Dim regValue As String
Dim valueType As Long

' query the Registry to check whether the DSN is already installed
' open the key
If RegOpenKeyEx(HKEY_CURRENT_USER, "Software\ODBC\ODBC.INI\" & sDSN, 0, _
KEY_ALL_ACCESS, hKey) = 0 Then
' zero means no error => Retrieve value of "DBQ" key
regValue = String$(1024, 0)
' Allocate Variable Space
If RegQueryValueEx(hKey, "DBQ", 0, valueType, regValue, _
Len(regValue)) = 0 Then
' zero means OK, so we can retrieve the value
If valueType = REG_SZ Then
sDBQ = Left$(regValue, InStr(regValue, vbNullChar) - 1)
End If
End If
' close the key
RegCloseKey hKey
End If

' Perform the action only if we're adding a DSN that doesn't exist
' or removing and existing DSN
If (sDBQ = "" And lAction = ODBC_ADD_DSN) Or (sDBQ <> "" And lAction = _
ODBC_REMOVE_DSN) Then

' check that the file actually exists
If Len(Dir$(sDBFile)) = 0 Then
MsgBox "Database file doesn't exist!", vbOKOnly + vbCritical
Exit Sub
End If
sAttributes = "DSN=" & sDSN & vbNullChar & "DBQ=" & sDBFile & vbNullChar
lngRet = SQLConfigDataSource(0&, lAction, sDriver, sAttributes)
End If
End Sub

Notice that there is a call to the GetKeyValue function. You can add this routine if you install the VB Template Manager Add-in. This add-in comes with VB6, but VB5 owners can download it from Microsoft web site. After you install the add-in, just issue the Tools and Add Code Snippet menu command, and select the Registry Access item in the dialog that appears.
Here's an example to create a DSN, called "DSN Creation Test", that points to a Access database:

sDriver = "Microsoft Access Driver (*.mdb)"
sName = "DSN Creation Test"
sFile = App.Path & "\MyDatabase.mdb"
MakeDSN sName, sDriver, sFile, ODBC_ADD_DSN
softdoctor 2000-03-03
  • 打赏
  • 举报
回复

ODBC API 函数SQLConfigDSN
929 2000-03-03
  • 打赏
  • 举报
回复
我想可以在注册表中填加有关ODBC注册的项目,在程序中填加ODBC数据源。
对注册表中的有这样几个地方需要注意:
HEKY_SOFTWARE\CURRENT_USER\ODBC\ODBC.INI可用ODBC在注册表中查找。另外,用一些安装程序装一些数据库软件,然后分析ODBC注册项的不同。就可知道应该在自己程序中如何修改。
此外,我想你如果只想在程序中动态地加入一个连接数据库的别名的话,可用DELPHI中的函数来完成。
procedure AddAlias(const Name, Driver: String; List: TStrings);
EXAMPLE:
var

MyList: TStringList;
begin
MyList := TStringList.Create;
try
with MyList do
begin
Add('SERVER NAME=IB_SERVER:/PATH/DATABASE.GDB');
Add('USER NAME=MYNAME');
end;
Session1.AddAlias('NewIBAlias', 'INTRBASE', MyList);
finally
MyList.Free;
end;
end;
渤海海峡 2000-03-03
  • 打赏
  • 举报
回复
这篇应该是你需要的。

在DELPHI程序中自动设置ODBC数据源
  在DELPHI数据库应用程序中,我们访问数据库通常有两种方法.一种是通过BDE数据库搜索
引擎,即利用DELPHI自带的数据库驱动程序,这种方法的优点是速度快,但应用范围有限,当
数据库版本更新时,有可能不能用于操作新的数据库;另一种方法是通过ODBC,这种方法的优
点是可以随操作系统(如WINDOWS)提供,作为标准接口能适应多种数据库,缺点是速度慢.在编
程时,我们可以根据需要选择其中的一种方法.
  在利用ODBC访问数据库时,通常的方法时是在ODBC管理面板中设置一个ODBC系统数据源
(系统DSN),然后在DBD中或在程序中设置一个数据库别名(Alias)对应该DSN,这样就可以如愿以
偿地操作数据库了.相信用DELPHI做过数据库应用的程序员对这方面已经很熟悉了,笔者就不多
说了.在实际应用中,笔者曾遇到过这样的情况,我们的数据库应用程序是依靠ODBC系统数据源
访问和操作数据库的,应用程序运行一直良好,直到某一天,一个对WINDOWS系统较为熟悉但又不
太精通的用户不慎修改或删除了我们预先设置的系统DSN......
  于是,笔者就开始研究怎么在程序中动态地设置ODBC系统DSN的内容,这样就可以增加自己程
序的坚固性了.经过整整一天对WINDOWS注册表的研究,终于找到了ODBC管理程序设置DSN的秘密
("天地自有公道,付出总会回报!",不是做广告!),现写出来与大家共享,也请高手指教.
  ODBC管理程序设置DSN的秘密在注册表中,不信可以到HKEY_LOCAL_MACHINE\Software\ODBC去
看看,肯定让你感觉已经成功了一半.
  首先来看看系统中已安装的ODBC数据库驱动程序.在HKEY_LOCAL_MACHINE\Software\ODBC\
ODBCInst.INI中,存放着已经安装了的ODBC数据库驱动程序的信息,从这里可以查到已安装的ODBC数
据库驱动程序对应的DLL文件等信息.在ODBCInst.INI\ODBC Drivers的各个键值中,键名是驱动程序
名称(如Microsoft Access Driver(*.mdb)),键值为“Installed”,表示驱动程序已安装.在
ODBCInst.INI\DriverName(DriverName为一个驱动程序名称,如Microsoft Access Driver(*.mdb))
中,有驱动程序的详细信息,我们主要从这里获得ODBC驱动程序对应的DLL文件的路径和文件名,即
键名Driver的键值,一般为"C:\WINDOWS\SYSTEM\FileName.DLL".
  然后来看系统DSN的注册信息,在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI中,存放着系统
DSN的注册信息,我们在ODBC管理面板设置的DSN参数就在这里.
  下面来看看创建一个ODBC系统DSN的步骤,即我们在ODBC管理面板中完成参数设置后,ODBC管理
程序是怎么在注册表中注册DSN信息的.以创建一个名称为MyAccess的Ms Access97类型的系统DSN为例,
我们指定的参数主要有数据库类型(Microsoft Access Driver(*.mdb))、数据源名称(MyAccess)、
数据源描述(我的ACCESS)、数据库路径(C:\Inetpub\wwwroot\Test.mdb),其它参数如用户名称、
用户密码、独占、只读、系统数据库、默认目录、缓冲区大小、扫描行数、页超时等采用系统
缺省参数.这时,注册系统DSN一般应有以下几个步骤:
  1.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\ODBC Data Sources中增加一个字符串键
值,为MyAccess = Microsoft Access Driver(*.mdb),其中分别为数据源名称和数据库类型.
这是在注册表中注册一个系统DSN名称.
  2.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI中创建一个子键(SubKey)MyAccess,即创
建一个键为HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess,然后在其下创建一些
键值,详细描述一个系统DSN的配置信息,主要信息有([]中的内容为笔者注释):
DBQ=C:\Inetpub\wwwroot\Test.mdb [字符串,表示数据库路径]
Description=我的ACCESS [字符串,表示数据库描述]
Driver=C:\PWIN98\System\odbcjt32.dll [字符串,表示驱动程序,可见ODBCINST.INI]
DriverId=0x00000019(25) [数字,表示驱动程序标识,不能改变]
FIL=Ms Access; [字符串,可能与过滤Filter有关]
SafeTransaction=0x00000000 [数字,可能表示支持事务性操作的个数]
UID="" [字符串,表示用户名称,此处为空字符串]
  3.在HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess中创建一个子键(SubKey)Engines,
再在其下创建子键(SubKey)Jet,即创建一个键为
HKEY_LOCAL_MACHINE\Software\ODBC\ODBC.INI\MyAccess\Engines\Jet,然后在其下创建一些
键值,详细描述一个系统DSN的数据库引擎配置信息,主要信息有([]中的内容为笔者注释):
ImplicitCommitSync=Yes [字符串,可能表示是否立即反映数据修改]
MaxBufferSize=0x00000200(512) [数字,表示缓冲区大小]
PageTimeout=0x00000005(5) [数字,表示页超时]
Threads=0x00000003(3) [数字,可能表示支持的最大线程数目]
UserCommitSync=Yes [字符串,可能表示是否立即将数据修改反映到用户]

  以上是建立一个系统DSN的基本信息(其它信息如选项或高级选项等信息也在这里设置,只不过因采用默认
信息,注册表里没有列出),我们在程序中按上述步骤操作注册表,同样也能增加一个系统DSN或修改其配置.
在下面的例子程序中,将按以上步骤建立一个系统DSN,请注意程序中的注释.

{*******************************************************
在本程序中,将创建一个ODBC系统数据源(DSN),
数据源名称:MyAccess 数据源描述:我的新数据源
数据库类型:ACCESS97
对应数据库:C:\Inetpub\wwwroot\test.mdb
*******************************************************}
{ 注意应在USES语句中包含Registry }
procedure TForm1.Button1Click(Sender: TObject);
var
registerTemp : TRegistry;
bData : array[ 0..0 ] of byte;
begin
registerTemp := TRegistry.Create; //建立一个Registry实例
with registerTemp do
begin
RootKey:=HKEY_LOCAL_MACHINE;//设置根键值为HKEY_LOCAL_MACHINE

//找到Software\ODBC\ODBC.INI\ODBC Data Sources
if OpenKey('Software\ODBC\ODBC.INI\ODBC Data Sources',True) then
begin //注册一个DSN名称
WriteString( 'MyAccess', 'Microsoft Access Driver (*.mdb)' );
end
else
begin//创建键值失败
memo1.lines.add('增加ODBC数据源失败');
exit;
end;
CloseKey;

//找到或创建Software\ODBC\ODBC.INI\MyAccess,写入DSN配置信息
if OpenKey('Software\ODBC\ODBC.INI\MyAccess',True) then
begin
WriteString( 'DBQ', 'C:\inetpub\wwwroot\test.mdb' );//数据库目录
WriteString( 'Description', '我的新数据源' );//数据源描述
WriteString( 'Driver', 'C:\PWIN98\SYSTEM\odbcjt32.dll' );//驱动程序DLL文件
WriteInteger( 'DriverId', 25 );//驱动程序标识
WriteString( 'FIL', 'Ms Access;' );//Filter依据
WriteInteger( 'SafeTransaction', 0 );//支持的事务操作数目
WriteString( 'UID', '' );//用户名称
bData[0] := 0;
WriteBinaryData( 'Exclusive', bData, 1 );//非独占方式
WriteBinaryData( 'ReadOnly', bData, 1 );//非只读方式
end
else//创建键值失败
begin
memo1.lines.add('增加ODBC数据源失败');
exit;
end;
CloseKey;

//找到或创建Software\ODBC\ODBC.INI\MyAccess\Engines\Jet
//写入DSN数据库引擎配置信息
if OpenKey('Software\ODBC\ODBC.INI\MyAccess\Engines\Jet',True) then
begin
WriteString( 'ImplicitCommitSync', 'Yes' );
WriteInteger( 'MaxBufferSize', 512 );//缓冲区大小
WriteInteger( 'PageTimeout', 10 );//页超时
WriteInteger( 'Threads', 3 );//支持的线程数目
WriteString( 'UserCommitSync', 'Yes' );
end
else//创建键值失败
begin
memo1.lines.add('增加ODBC数据源失败');
exit;
end;
CloseKey;

memo1.lines.add('增加新ODBC数据源成功');

Free;
end;
end;

  以上程序在PWIN98+DELPHI3.0下调试通过.

  下面是创建常见数据库类型的DSN需要设置的信息([]为注释内容,除特殊注释外,各参数可见前面说明):
  1.Access(Microsoft Access Driver(*.mdb))
DBQ、Description、Driver[odbcjt32.dll]、DriverID[25]、FIL[Ms Access;]、
SafeTransaction[默认为0]、UID[默认为空]、
Engines\Jet\ImplicitCommitSync[默认为Yes]、Engines\Jet\MaxBufferSize[默认512]、
Engines\Jet\PageTimeout[默认为512]、Engines\Jet\Threads[默认为3]、
Engines\Jet\UserCommitSync[默认为Yes]
可选设置:SystemDb[字符串,系统数据库的路径]、
ReadOnly[二进制,是否以只读方式打开,1为是,默认为0]、
Exclusive[二进制,是否以独占方式打开,1为是,默认为0]、
PWD[字符串,用户密码]

  2.EXCEL(Microsoft Excel Driver(*.xls))
DBQ[Excel97(=path\xxx.xls)、5.0/7.0(=path\xxx.xls)、4.0(=path)、3.0(=path)]、
Description、Driver[odbcjt32.dll]、
DefaultDir[Excel97(<>DBQ)、5.0/7.0(<>DBQ)、4.0(=DBQ)、3.0(=DBQ)]、
DriverID[790(Excel97)、22(5.0/7.0)、278(4.0)、534(3.0)]、
FIL[Excel5.0;]、ReadOnly、SafeTransaction、UID、
Engines\Excel\ImplicitCommitSync、Engines\Excel\MaxScanRows[数字,扫描行数,默认为8]、
Engines\Excel\Threads、Engines\Excel\UserCommitSync、
Engines\Excel\FirstRowHasName[二进制,第一行是否是域名,1表示是,默认为1]

注: Excel97和Excel7.0/5.0的DBQ对应一个XLS文件,而Excel4.0和Excel3.0则对应一个目录;
  DefaultDir对应一个目录,在Excel97和Excel7.0/5.0中是DBQ所对应的路径,而在
  Excel4.0和Excel3.0下则与DBQ相同;各个版本的DriverID不同.

  3.dBase(Microsoft dBase Driver(*.dbf))
DefaultDir[字符串,数据库文件所在目录]、Description、Driver[odbcjt32.dll]、
DriverID[277(IV)、533(5.0)]、FIL[dbase III;]、SafeTransaction、UID、
Engines\Xbase\ImplicitCommitSync、
Engines\Xbase\Collating[字符串,排序依据,可为ASCII、International、Norwegian-Danish、
Swedish-Finnish]、
Engines\Xbase\Deleted[二进制,是否不显示被软删除的记录,0表示显示,默认为1]、
Engines\Xbase\PageTimeout[默认为600]、Engines\Xbase\UserCommitSync、
Engines\Xbase\Threads、Engines\Xbase\Statistics[二进制,是否用大约的行数,1为是,默认0]
注:(dBaseIV和dBase5.0两个版本的DriverId有不同)

  4.Foxpro(Microsoft Foxpro Driver(*.dbf))
DefaultDir[数据库文件所在目录]、Description、Driver[odbcjt32.dll]、
DriverID[536(2.6)、280(2.5)]、FIL[Foxpro 2.0;]、SafeTransaction、UID、
Engines\Xbase\Collating[字符串,排序依据,可为ASCII、International]、
Engines\Xbase\Deleted[二进制,是否不显示被软删除的记录,0表示显示,默认为1]、
Engines\Xbase\PageTimeout[默认为600]、Engines\Xbase\UserCommitSync、
Engines\Xbase\Threads、Engines\Xbase\Statistics[二进制,是否用大约的行数,1为是,默认0]
注:(Foxpro2.5和Foxpro2.6两个版本的DriverId有不同)


  把上面程序做成一个COM或ActiveX控件吧,在很多高级程序设计语言如DELPHI、C++Buider、VB、VC、
PB中都能用到的.

(作者:深圳王发军 wangfajun@163.net http://wangfajun.163.net)

sess 2000-03-03
  • 打赏
  • 举报
回复
同意softdoctor看法,我就是这么做的,改键值是不是夸张了一点

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧