- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
给定:
问题:
换句话说,假设我们谈论的是Sql Server CE 3.5,如何让下面的代码成功:
IDBInitializePtr spDBInitialize;
HRESULT hr = spDBInitialize.CreateInstance(CLSID_SQLSERVERCE35, NULL);
请注意,机器是干净的,代码是作为受限帐户运行的。
编辑
还有一个问题。代码是 C++,我不能使用 Ado.NET
最佳答案
spDBInitialize.CreateInstance()
执行以下操作:
LoadLibrary()
GetProcAddress
DllGetClassObject
获取 IClassFactory
IClassFactory
来处理您的 CreateInstance(NULL, IID_IDBInitialize, (void**) &spIDBInitialize)
请求在您的情况下,您确实无法通过第一步,因为您的 DLL 未在 Windows 注册表中注册。
但是,因为您知道 SQL Server CE DLL 的位置,所以您可以通过让您的代码仅实现 3、4、5 和 6 来解决这个问题。
这是一个使用 CoCreateInstance 替换打开 SDF 的 C++ 控制台应用程序:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <oleauto.h>
#include <atlbase.h>
#include "C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v3.5\Include\sqlce_oledb.h"
#include "C:\Program Files (x86)\Microsoft SQL Server Compact Edition\v3.5\Include\sqlce_err.h"
//----------------------------------------------------------------------
// Creates a COM object using an HMODULE instead of the Windows Registry
//----------------------------------------------------------------------
HRESULT DllCoCreateInstance(HMODULE hModule, REFCLSID rclsid, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppv)
{
HRESULT hr = S_OK;
if (hModule == NULL)
{
return E_INVALIDARG;
}
BOOL (WINAPI*DllGetClassObject)(REFCLSID, REFIID, LPVOID) = NULL;
(FARPROC&) DllGetClassObject = GetProcAddress(hModule, "DllGetClassObject");
if (DllGetClassObject == NULL)
{
return HRESULT_FROM_WIN32(GetLastError());
}
CComPtr<IClassFactory> spIClassFactory;
hr = DllGetClassObject(rclsid, IID_IClassFactory, &spIClassFactory);
if (FAILED(hr))
{
return hr;
}
return spIClassFactory->CreateInstance(pUnkOuter, riid, ppv);
}
//----------------------------------------------------------------------
// Open a close a SDF file
//----------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = S_OK;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// Need a loaded library so we can CoCreateInstance without the Windows Registry.
HMODULE hModule = LoadLibrary(L"C:\\Program Files (x86)\\Microsoft SQL Server Compact Edition\\v3.5\\sqlceoledb35.dll");
// Open a SQL Server CE 3.5 database without using Windows Registry.
CComPtr<IDBInitialize> spIDBInitialize;
//hr = spIDBInitialize.CoCreateInstance(CLSID_SQLSERVERCE_3_5);
hr = DllCoCreateInstance(hModule, CLSID_SQLSERVERCE_3_5, NULL, IID_IDBInitialize, (void**) &spIDBInitialize);
CComPtr<IDBProperties> spIDBProperties;
hr = spIDBInitialize->QueryInterface(IID_IDBProperties, (void**) &spIDBProperties);
CComVariant varDataSource(OLESTR("InsertYourSampleDatabase.SDF"));
DBPROP prop = { DBPROP_INIT_DATASOURCE, DBPROPOPTIONS_REQUIRED, 0, DB_NULLID, varDataSource };
DBPROPSET propSet = {&prop, 1, DBPROPSET_DBINIT};
hr = spIDBProperties->SetProperties(1, &propSet);
spIDBProperties = NULL;
hr = spIDBInitialize->Initialize();
// @@TODO: Do your regular OLEDB code with the opened database.
//...
// Close COM objects
spIDBInitialize = NULL;
CoUninitialize();
return 0;
}
代码片段中缺少的一些东西:
FreeLibrary()
要获得有意义的 SQL Server CE 操作错误消息,您应该查阅 Microsoft MSDN 文章 Using OLE DB Error Objects (SQL Server Compact Edition) .我通常从这里的精简版开始:
if (FAILED(hr))
{
CComPtr<IErrorInfo> spIErrorInfo;
GetErrorInfo(0, &spIErrorInfo);
if (spIErrorInfo != NULL)
{
CComBSTR bstrError;
spIErrorInfo->GetDescription(&bstrError);
// @@TODO: Do stuff with bstrError
wprintf("%s\r\n", (BSTR) bstrError);
}
}
只部署整个 SQL Server CE 3.5 文件夹更容易和更安全,但是,如果您想要一个最小的集合,我相信以下文件对您的方案很重要:
作为引用,我认为您不需要的文件是:
关于c++ - 无需安装即可使用 SqlServer CE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9102471/
在我的 Windows 类库(由 MVC 网站使用)中,我安装了 NugetPackage Microsoft.SqlServer.Types (Spatial)。 现在,我正在使用 ado.net
测试sql: 复制代码代码如下: SET STATISTICS IO ON SET STATISTICS TIME ON SELECT COUNT(1)&n
我正在从 SqlConnection 构建 DbContext。当我使用它时,我收到以下错误: The Entity Framework provider type 'System.Data.Enti
我使用dotNet 4.5创建了WCF服务。数据库层是使用Entity Framework 6构建的。 我使用IIS 8托管了该服务。它运行正常。 现在,我需要使用Windows窗体客户端使用该服务,
我正在尝试从 SqlServer 1 上的 sql 数据库中导出一些表。在我们的内部网 LAN(就在我旁边)中有一个我制作的临时 Sql Server,称为 SqlServer 2。 我不想备份整个数
Error 1 Copying file bin\EntityFramework.SqlServer.xml to obj\Debug\Package\PackageTmp\bin\Entit
我正在尝试使用 SMO 通过 Powershell 恢复数据库,但是当我尝试定义和使用服务器对象时,出现以下错误: Cannot convert argument "srv", with value:
出于某种原因,我需要将我的表列之一从“NOT NULL”更新为“NULL”。命令很简单: ALTER TABLE TBLOGDOCMESSAGE ALTER COLUMN PROCESSID BIGI
我想知道我正在尝试做的事情是否可行。我相信它是在 TSQL 中使用 PIVOT 函数,但对 PIVOT 函数没有足够的经验来知道从哪里开始。 基本上,我正在尝试采用以下名为 #tmpbudgetdat
我正在尝试将子查询作为带有条件的列。 我从 SQL Server 得到的错误是: 子查询返回了 1 个以上的值。当子查询跟随 =、!=、、>= 或当子查询用作表达式时,这是不允许的。 我正在选择更多的
我有一个正在查询的 SQL 服务器数据库,我只想在特定行为空时获取信息。我使用了一个 where 语句,例如: WHERE database.foobar = NULL 它不返回任何东西。但是,我知道
1、拼接字符串(整个字符串不分割)步骤: 首先在字符串的前后加单引号; 字符串中的变量以'''+@para+'''在字符串中表示; 若在执行时存在类型转换错误,则应用相应的类型
说明: 收缩日志的原因有很多种,有些是考虑空间不足,有些则是应用程序限制导致的。 ?
Rand()函数是系统自带的获取随机数的函数,可以直接运行select rand() 获取0~1之间的float型的数字。 如果想要获取0~100之间的整数随机数,可以这样使用 select ro
将以下内容保存为 openSql.bat 双击运行即可 复制代码 代码如下: @echo ========= SQL Server Ports =================== @ech
新增的APPLY表运算符把右表表达式应用到左表表达式中的每一行。它不像JOIN那样先计算那个表表达式都可以,APPLY必选先逻辑地计算左表达式。这种计算输入的逻辑顺序允许吧右表达式关联到左表表达式。
SQL Server本身提供了这么一个DMV来返回这些信息,它就是sys.dm_exec_sessions 。 比如在我的机器上做一下查询: 复制代码 代码如下: SELECT * FROM
尽管从技术上讲,其它排名函数的计算与ROW_NUMBER类似,但它们的的实际应用却少很多。RANK和DENSE——RANK主要用于排名和积分。NTILE更多地用于分析。 先创建一个示例表: 复制
1、文件和文件组的含义与关系 每个数据库有一个主数据文件.和若干个从文件。文件是数据库的物理体现。 文件组可以包括分布在多个逻辑分区的文件,实现负载平衡。文件组允许对文件进行分组,以便于管理和数据的
我想很多人都知道,在oracle里面,存储过程里面可以传入数组(如int[]),也就是说,可以传多条记录到数据,从而一起更新。减少数据库的请求次数。 但SqlServer呢?bulk Insert这
我是一名优秀的程序员,十分优秀!