pragma autonomous_transaction : restrict_references(<fuctionname>,wnds) and serially_resumable

本文通过创建并使用 Oracle PL/SQL 包演示了如何实现串行可重用性和自治事务特性。首先定义了一个串行可重用包 pkg1 来管理变量状态,并展示其在不同会话中的行为。接着创建了一个名为 pkg2 的包,该包包含一个自治事务函数 fn_auto,用于在查询中执行 DML 操作。

pragma : serially_reusable


SQL> CREATE PACKAGE pkg1 IS

   PRAGMA SERIALLY_REUSABLE;
   num NUMBER := 0;
   PROCEDURE init_pkg_state(n NUMBER);
   PROCEDURE print_pkg_state;
END pkg1;
/  2    3    4    5    6    7


Package created.


SQL> CREATE PACKAGE BODY pkg1 IS
   PRAGMA SERIALLY_REUSABLE;
   PROCEDURE init_pkg_state (n NUMBER) IS
   BEGIN
      pkg1.num := n;
   END;
   PROCEDURE print_pkg_state IS
   BEGIN
      dbms_output.put_line('Num: ' || pkg1.num);
   END;
END pkg1;
/  2    3    4    5    6    7    8    9   10   11   12


Package body created.


SQL>
SQL>
SQL> exec pkg1.init_pkg_state(10);


PL/SQL procedure successfully completed.

SQL> exec pkg1.print_pkg_state;
Num: 0


PL/SQL procedure successfully completed.


pragma :autonomous_transaction

SQL> create table t(ab date);


Table created.


SQL> create or replace package pkg2 is
             function fn_auto return number;
           end pkg2;
/  2    3    4


Package created.


SQL> create or replace package body pkg2 is
            function fn_auto return number
             is
            begin
                insert into t values(sysdate);
                commit;
                return 1;
            end;
         end pkg2;
 /  2    3    4    5    6    7    8    9   10


Package body created.


SQL>  select pkg2.fn_auto() test from dual;
 select pkg2.fn_auto() test from dual
        *
ERROR at line 1:
ORA-14551: cannot perform a DML operation inside a query
ORA-06512: at "QDL.PKG2", line 5


SQL> create or replace package body pkg2 is
function fn_auto return number
is
pragma autonomous_transaction;
begin
insert into t values(systimestamp);
commit;
 return 1;
end;
end pkg2;
/  2    3    4    5    6    7    8    9   10   11


Package body created.


SQL>  select pkg2.fn_auto() test from dual;


      TEST
----------
         1


pragma :restrict_references(fn_auto,wnds)

make the compiler compile the function fn_auto according to WNDS (write no database ) , so after the package boday created, you see the compile error directly.


C:/Users/Administrator/Documents/untitled1.cpp 7 0 [警告] ignoring '#pragma comment ' [-Wunknown-pragmas] C:/Users/Administrator/Documents/untitled1.cpp 0 -1 In function 'void HandleClient(SOCKET)': C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/locale_facets.h 48 0 In file included from C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/locale_facets.h C:/Users/Administrator/Documents/untitled1.cpp 35 21 [错误] no matching function for call to 'find(std::vector<long long unsigned int>::iterator, std::vector<long long unsigned int>::iterator, SOCKET&)' C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/streambuf_iterator.h 421 5 [说明] candidate: 'template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT, std::char_traits<_CharT> > >::__type std::find(std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, const _CharT2&)' C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/streambuf_iterator.h 421 5 [说明] template argument deduction/substitution failed: C:/Users/Administrator/Documents/untitled1.cpp 35 21 [说明] '__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >' is not derived from 'std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >' C:/Users/Administrator/Documents/untitled1.cpp 7 0 [警告] ignoring '#pragma comment ' [-Wunknown-pragmas] C:/Users/Administrator/Documents/untitled1.cpp 0 -1 In function 'void HandleClient(SOCKET)': C:/Users/Administrator/Documents/untitled1.cpp 35 28 [错误] no matching function for call to 'find(std::vector<long long unsigned int>::iterator, std::vector<long long unsigned int>::iterator, SOCKET&)' C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/locale_facets.h 48 0 In file included from C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/locale_facets.h C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/streambuf_iterator.h 421 5 [说明] candidate: 'template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT, std::char_traits<_CharT> > >::__type std::find(std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >, const _CharT2&)' C:/Program Files/RedPanda-Cpp/mingw64/lib/gcc/x86_64-w64-mingw32/11.5.0/include/c++/bits/streambuf_iterator.h 421 5 [说明] template argument deduction/substitution failed: C:/Users/Administrator/Documents/untitled1.cpp 35 28 [说明] '__gnu_cxx::__normal_iterator<long long unsigned int*, std::vector<long long unsigned int> >' is not derived from 'std::istreambuf_iterator<_CharT, std::char_traits<_CharT> >'
最新发布
08-11
<think>我们遇到了编译错误,主要问题在于: 1. 在`HandleClient`函数中,使用`std::find`在`std::vector<SOCKET>`中查找`clientSocket`时出错。 2. 错误信息表明编译器无法找到匹配的`find`函数,因为`SOCKET`类型(在Windows下通常是`unsigned long long`或类似)与迭代器类型不匹配。 原因分析: 在Windows中,`SOCKET`类型定义如下(在`winsock2.h`中): typedef UINT_PTR SOCKET; 而`UINT_PTR`是一个与指针大小相同的无符号整数。在64位系统上,它是64位无符号整数(即`unsigned long long`)。 但是,`std::find`是一个模板函数,需要比较`SOCKET`和`vector`中元素的类型。我们的`clients`向量定义为`std::vector<SOCKET>`,所以元素类型是`SOCKET`(即`UINT_PTR`)。 然而,错误信息显示编译器试图将`__normal_iterator<long long unsigned int*`(即`SOCKET*`)与`std::istreambuf_iterator`进行匹配,这显然不对。 实际上,问题可能在于我们没有包含`<algorithm>`头文件,因为`std::find`在`<algorithm>`中声明。 解决方案: 1. 包含`<algorithm>`头文件。 2. 另外,我们还有一个关于`#pragma comment`的警告,因为我们在MinGW环境下使用,而MinGW可能不支持`#pragma comment(lib, ...)`,所以我们可以使用条件编译或者确保链接时加上`-lws2_32`。 修改步骤: - 在代码开头添加`#include <algorithm>` - 对于`#pragma comment`,我们可以保留,因为它在MSVC上是有效的,在MinGW下会忽略(只是警告,不影响编译)。或者我们可以去掉,然后在编译时手动链接库。 另外,注意代码中还有一处错误:在`RunServer`函数中,当服务器运行时,我们使用了无限循环,但在退出时没有关闭套接字和清理Winsock。同样,在客户端退出时也有类似问题。但当前问题主要是编译错误。 修改后的代码(解决编译错误): 在头文件包含部分添加`#include <algorithm>` 同时,注意错误信息中提示的`no matching function for call to 'find'`,正是由于缺少`<algorithm>`头文件导致的。 另外,我们注意到错误信息中还有: [警告] ignoring '#pragma comment ' [-Wunknown-pragmas] 这个警告是因为在MinGW中,`#pragma comment(lib, "ws2_32.lib")`可能不被支持。我们可以使用以下方式替代: #ifdef _WIN32 #pragma comment(lib, "ws2_32.lib") #endif 或者,在编译时手动链接:对于g++,使用`-lws2_32`选项。 由于问题主要是编译错误,我们优先解决编译错误。 修改后的代码(部分): #include <algorithm> // 添加这一行 然后重新编译。 但是,根据错误信息,还有一处是: [错误] no matching function for call to 'find(std::vector<long long unsigned int>::iterator, std::vector<long long unsigned int>::iterator, SOCKET&)' 添加了`<algorithm>`后,应该可以解决,因为`std::find`在`<algorithm>`中。 因此,我们修改代码,添加`#include <algorithm>`。 另外,我们还可以考虑将`SOCKET`类型转换为整数类型进行比较,但是`std::find`是模板函数,可以处理整数类型,所以只要包含正确的头文件即可。 修改后的完整代码(仅添加头文件):</think>您的代码编译错误主要涉及两个问题:缺少`<algorithm>`头文件导致`std::find`不可用,以及`#pragma comment`在MinGW环境下的兼容性问题。以下是修复后的代码: ```cpp #include <winsock2.h> #include <ws2tcpip.h> #include <iostream> #include <thread> #include <vector> #include <mutex> #include <algorithm> // 添加algorithm头文件解决std::find问题 // 移除不兼容的#pragma comment,改用编译选项-lws2_32 // #pragma comment(lib, "ws2_32.lib") // MinGW下需替换为编译指令 std::mutex mtx; SOCKET serverSocket = INVALID_SOCKET; std::vector<SOCKET> clients; void HandleClient(SOCKET clientSocket) { char buffer[1024]; int bytesReceived; while (true) { bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0); if (bytesReceived <= 0) break; buffer[bytesReceived] = '\0'; std::cout << "收到消息: " << buffer << std::endl; // 广播消息给所有客户端 std::lock_guard<std::mutex> lock(mtx); for (SOCKET sock : clients) { if (sock != clientSocket) { send(sock, buffer, bytesReceived, 0); } } } // 移除断开的客户端 std::lock_guard<std::mutex> lock(mtx); auto it = std::find(clients.begin(), clients.end(), clientSocket); if (it != clients.end()) clients.erase(it); closesocket(clientSocket); } void RunServer(int port) { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = INADDR_ANY; serverAddr.sin_port = htons(port); bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)); listen(serverSocket, SOMAXCONN); std::cout << "服务器已启动,等待连接... (端口: " << port << ")\n"; while (true) { SOCKET clientSocket = accept(serverSocket, NULL, NULL); if (clientSocket != INVALID_SOCKET) { std::lock_guard<std::mutex> lock(mtx); clients.push_back(clientSocket); std::thread(HandleClient, clientSocket).detach(); std::cout << "新客户端连接\n"; } } } void RunClient(const char* ip, int port) { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; inet_pton(AF_INET, ip, &serverAddr.sin_addr); serverAddr.sin_port = htons(port); if (connect(sock, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) { std::cerr << "连接失败\n"; return; } std::cout << "已连接到服务器\n"; // 接收消息线程 std::thread receiver([sock]() { char buffer[1024]; while (true) { int bytesReceived = recv(sock, buffer, sizeof(buffer) - 1, 0); if (bytesReceived <= 0) break; buffer[bytesReceived] = '\0'; std::cout << "来自服务器: " << buffer << std::endl; } }); // 发送消息 char message[1024]; while (true) { std::cin.getline(message, sizeof(message)); if (strlen(message) == 0) continue; send(sock, message, strlen(message), 0); } receiver.join(); closesocket(sock); WSACleanup(); } int main() { int choice; std::cout << "1. 启动服务器\n2. 连接服务器\n选择: "; std::cin >> choice; std::cin.ignore(); if (choice == 1) { RunServer(12345); } else if (choice == 2) { char ip[16]; std::cout << "输入服务器IP: "; std::cin.getline(ip, sizeof(ip)); RunClient(ip, 12345); } return 0; } ``` ### 修复说明: 1. **添加`<algorithm>`头文件**: - 解决了`std::find`函数未定义的编译错误 - 这是导致`no matching function for call to 'find'`错误的主要原因 2. **处理`#pragma comment`警告**: - 移除了`#pragma comment(lib, "ws2_32.lib")`行 - 改用编译时手动链接:`g++ -o chat.exe chat.cpp -lws2_32 -lstdc++fs -static` - 在MinGW环境下更可靠 3. **其他注意事项**: - 确保使用C++11或更高标准编译 - 在Windows系统需要安装MinGW-w64或使用Visual Studio - 运行时需在局域网内测试 ### 编译指令(MinGW): ```bash g++ -o chat.exe chat.cpp -lws2_32 -std=c++11 -static ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值