gpt4 book ai didi

delphi - 有没有什么简单的方法可以比较连接字符串而无需自己解析它?

转载 作者:行者123 更新时间:2023-12-03 14:56:29 27 4
gpt4 key购买 nike

我需要能够比较两个不同的连接字符串并确定它们是否是相同的信息。我无法进行简单的字符串比较,因为属性可以以不同的方式布局,但仍然表示相同的连接。

在我对此进行自己的比较之前,是否已经有一些东西可以做到这一点?

我已经寻找了一种方法,但找不到任何关于此的信息。

最佳答案

您可以使用IDataInitialize::GetDataSource方法,它从给定的连接字符串返回未初始化的数据源对象。由于此方法返回指向 IUnknown 类型的数据源对象的指针,因此您无法直接比较为两个比较的连接字符串获取的对象。然而,you can query IDBProperties那些未初始化的数据源对象上的接口(interface)使您可以访问给定提供程序支持的所有属性。

要获取属性集,您需要使用 IDBProperties::GetProperties方法。这将返回 DBPROPSET结构体,其中包含 DBPROP 的数组元素(属性)。然后,您只需迭代该数组并以您需要的方式比较这两个数据源对象的属性。

如果连接字符串相等,则以下 IsSameConnStr 函数返回 True,否则返回 False。请注意,所使用的属性值比较不区分大小写,但 DBPROP_AUTH_PASSWORD 除外。属性,与区分大小写进行比较:

uses
ActiveX, ComObj, OleDB;

function IsSameVarWideStr(const AValue1, AValue2: OleVariant;
ACaseSensitive: Boolean = False): Boolean;
begin
Result := VarType(AValue1) = VarType(AValue2);
if Result then
begin
if ACaseSensitive then
Result := WideCompareStr(VarToWideStr(AValue1),
VarToWideStr(AValue2)) = 0
else
Result := WideCompareText(VarToWideStr(AValue1),
VarToWideStr(AValue2)) = 0;
end;
end;

function IsSameConnStr(const AConnStr1, AConnStr2: WideString): Boolean;
var
I: Integer;
DataSrc1: IUnknown;
DataSrc2: IUnknown;
DataInit: IDataInitialize;
PropSet1: PDBPropSet;
PropSet2: PDBPropSet;
PropSetCnt1: ULONG;
PropSetCnt2: ULONG;
Properties1: IDBProperties;
Properties2: IDBProperties;
const
DBPROP_AUTH_PASSWORD = $00000009;
begin
// first check if the input connection strings aren't exactly the same
Result := CompareStr(AConnStr1, AConnStr2) = 0;
// if they are not same, then...
if not Result then
begin
// create IDataInitialize object instance
OleCheck(CoCreateInstance(CLSID_DataLinks, nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IID_IDataInitialize, DataInit));
// get data source objects for both input connection strings
OleCheck(DataInit.GetDataSource(nil, CLSCTX_INPROC_SERVER,
PWideChar(AConnStr1), IUnknown, DataSrc1));
OleCheck(DataInit.GetDataSource(nil, CLSCTX_INPROC_SERVER,
PWideChar(AConnStr2), IUnknown, DataSrc2));
// query for IDBProperties objects of the data source objects
if Succeeded(DataSrc1.QueryInterface(IID_IDBProperties, Properties1)) and
Succeeded(DataSrc2.QueryInterface(IID_IDBProperties, Properties2)) then
begin
// get properties of data source objects
OleCheck(Properties1.GetProperties(0, nil, PropSetCnt1, PropSet1));
OleCheck(Properties2.GetProperties(0, nil, PropSetCnt2, PropSet2));
try
// same DB provider will have the same set of initialization properties,
// so the first check might be the property count, if that differs, then
// at least DB provider is different, so if this equals, then...
if PropSetCnt1 = PropSetCnt2 then
begin
// initialize positive result
Result := True;
// iterate all the properties
for I := 0 to PropSet1.cProperties - 1 do
begin
// check if we're comparing the same property and if so, compare the
// property values; for password property compare the value with case
// sensitivity, for all the others case insensitively; if any of this
// doesn't match, we're done with False result and we can exit
if (PropSet1.rgProperties[I].dwPropertyID <>
PropSet2.rgProperties[I].dwPropertyID) or
not IsSameVarWideStr(PropSet1.rgProperties[I].vValue,
PropSet2.rgProperties[I].vValue,
PropSet1.rgProperties[I].dwPropertyID = DBPROP_AUTH_PASSWORD) then
begin
Result := False;
Break;
end;
end;
end;
finally
// release the property sets; note that you should avoid this common
// try..finally block and that you should free also each property array
// element by using IMalloc::Free; why I've used CoTaskMemFree see this
// question http://stackoverflow.com/q/3079508/960757
CoTaskMemFree(PropSet1);
CoTaskMemFree(PropSet2);
end;
end;
end;
end;

我认为用法很清楚,所以我宁愿提及一些连接字符串的结果:

IsSameConnStr = True
AConnStr1: Provider=MSDASQL.1;Persist Security Info=True;Data Source=datasource
AConnStr2: Provider=MSDASQL.1;Persist Security Info=True;Data Source=DATASOURCE

IsSameConnStr = True
AConnStr1: Provider=MSDASQL.1;Data Source=datasource;Persist Security Info=True
AConnStr2: Provider=MSDASQL.1;Persist Security Info=True;Data Source=DATASOURCE

IsSameConnStr = True
AConnStr1: Provider=MSDASQL.1;Password=PASSWORD;Data Source=datasource;Persist Security Info=True
AConnStr2: Provider=MSDASQL.1;Data Source=DATASOURCE;Password=PASSWORD;Persist Security Info=True

IsSameConnStr = False - password differs in case sensitivity
AConnStr1: Provider=MSDASQL.1;Password=PASSWORd;Data Source=datasource;Persist Security Info=True
AConnStr2: Provider=MSDASQL.1;Data Source=DATASOURCE;Password=PASSWORD;Persist Security Info=True

关于delphi - 有没有什么简单的方法可以比较连接字符串而无需自己解析它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15237234/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com