更新时间:2022-12-01 15:47:54
作为我的评论的后续文章,这是我的(有点不那么简单)示例,在这里起作用:
As a follow up to my comment, here is my (somewhat no-so-mimimal) example that works here:
一个非常简单的存储过程:
A very simple stored procedure:
USE [Test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER procedure [dbo].[foo]
@p1 int
AS
RETURN 13 + @p1
并且已经使用gui工具创建了该过程的同义词,名为dbo.fooSyn
.
And a synonym to that procedure has been created (using gui tools) named dbo.fooSyn
.
我可以在SQL Server 2014 Management Studio中执行这两项操作:
I can execute both from within SQL Server 2014 Management studio:
execute foo @p1 = 2
GO
execute fooSyn @p1 = 3
GO
两个语句均完整无误.
这是我的测试代码,使用该名称执行一次,并使用同义词执行一次:
And here is my test code to execute once using the name and once using the synonym:
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <sql.h>
#include <sqlext.h>
#include <sqlucode.h>
void printErrDbc(SQLHDBC hDbc)
{
SQLSMALLINT recNr = 1;
SQLRETURN ret = SQL_SUCCESS;
while (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLWCHAR errMsg[SQL_MAX_MESSAGE_LENGTH + 1];
SQLWCHAR sqlState[5 + 1];
errMsg[0] = 0;
SQLINTEGER nativeError;
SQLSMALLINT cb = 0;
ret = SQLGetDiagRec(SQL_HANDLE_DBC, hDbc, recNr, sqlState, &nativeError, errMsg, SQL_MAX_MESSAGE_LENGTH + 1, &cb);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
std::wcerr << L"ERROR; native: " << nativeError << L"; state: " << sqlState << L"; msg: " << errMsg << std::endl;
}
++recNr;
}
}
void printErrStmt(SQLHSTMT hStmt)
{
SQLSMALLINT recNr = 1;
SQLRETURN ret = SQL_SUCCESS;
while (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLWCHAR errMsg[SQL_MAX_MESSAGE_LENGTH + 1];
SQLWCHAR sqlState[5 + 1];
errMsg[0] = 0;
SQLINTEGER nativeError;
SQLSMALLINT cb = 0;
ret = SQLGetDiagRec(SQL_HANDLE_STMT, hStmt, recNr, sqlState, &nativeError, errMsg, SQL_MAX_MESSAGE_LENGTH + 1, &cb);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
std::wcerr << L"ERROR; native: " << nativeError << L"; state: " << sqlState << L"; msg: " << errMsg << std::endl;
}
++recNr;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SQLRETURN nResult = 0;
SQLHANDLE handleEnv = 0;
nResult = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, (SQLHANDLE*)&handleEnv);
nResult = SQLSetEnvAttr(handleEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, SQL_IS_INTEGER);
SQLHANDLE handleDBC = 0;
nResult = SQLAllocHandle(SQL_HANDLE_DBC, handleEnv, (SQLHANDLE*)&handleDBC);
SQLWCHAR strConnect[256] = L"Driver={SQL Server Native Client 11.0};Server=.\\INSTANCE;Database=Test;Trusted_Connection=yes;";
SQLWCHAR strConnectOut[1024] = { 0 };
SQLSMALLINT nNumOut = 0;
nResult = SQLDriverConnect(handleDBC, NULL, (SQLWCHAR*)strConnect, SQL_NTS, (SQLWCHAR*)strConnectOut, sizeof(strConnectOut),
&nNumOut, SQL_DRIVER_NOPROMPT);
if (!SQL_SUCCEEDED(nResult))
{
printErrDbc(handleDBC);
}
nResult = SQLSetConnectAttr(handleDBC, SQL_ATTR_AUTOCOMMIT, (SQLUINTEGER)SQL_AUTOCOMMIT_OFF, NULL);
if (!SQL_SUCCEEDED(nResult))
{
printErrDbc(handleDBC);
}
SQLHSTMT handleStatement = 0;
nResult = SQLAllocHandle(SQL_HANDLE_STMT, handleDBC, (SQLHANDLE*)&handleStatement);
if (!SQL_SUCCEEDED(nResult))
{
printErrDbc(handleDBC);
}
// Bind return code
SQLINTEGER res = 0;
SQLLEN cb = 0;
SWORD sParm1 = 0;
SQLLEN cbParm1 = SQL_NTS;
nResult = SQLBindParameter(handleStatement, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &sParm1, 0, &cbParm1);
if (!SQL_SUCCEEDED(nResult))
{
printErrStmt(handleStatement);
}
// And call using synonym name
nResult = SQLExecDirect(handleStatement, L"{? = call fooSyn(3)}", SQL_NTS);
if (!SQL_SUCCEEDED(nResult))
{
printErrStmt(handleStatement);
}
nResult = SQLFetch(handleStatement);
std::wcout << L"Result is: " << sParm1 << std::endl;
// Note: It also works using EXECUTE - but I dont remember how to read return value like that.
nResult = SQLExecDirect(handleStatement, L"execute foo @p1 = 2", SQL_NTS);
if (!SQL_SUCCEEDED(nResult))
{
printErrStmt(handleStatement);
}
else
{
std::wcout << L"Working using name" << std::endl;
}
nResult = SQLExecDirect(handleStatement, L"execute fooSyn @p1 = 2", SQL_NTS);
if (!SQL_SUCCEEDED(nResult))
{
printErrStmt(handleStatement);
}
else
{
std::wcout << L"Working using synonym" << std::endl;
}
return 0;
}
这将打印出预期的输出:
This prints out the expected output:
Result is: 16
Working using name
Working using synonym
那么,您的设置有什么区别?
So, what is the difference to your setup?
总结我的设置: