home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 32 / IOPROG_32.ISO / SOFT / SqlEval7 / devtools / samples / ODS / xp_param / xp_param.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-20  |  5.5 KB  |  187 lines

  1. // This is an example of an extended procedure DLL built with Open Data
  2. // Services. The function within the DLL can be invoked by using the
  3. // extended stored procedures support in SQL Server.
  4. //
  5. // For more information on Open Data Services refer to the Microsoft Open 
  6. // Data Services Programmer's Reference.
  7. //
  8. // xp_srv_paraminfo_sample accepts parameters from a Transact-SQL statement.
  9. // It analyzes each parameter then posts a result set to the client
  10. // containing information about each parameter and the parameter's value.
  11. //
  12. // The Transact-SQL script xp_param.sql installs and exercises the extended
  13. // stored procedure.
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <windows.h>
  19. #include <srv.h>
  20. #include <time.h>
  21.  
  22. // Macros -- return codes
  23. #define XP_NOERROR      0
  24. #define XP_ERROR        1
  25.  
  26. #define MAX_SERVER_ERROR 20000
  27. #define XP_PARAM_ERROR MAX_SERVER_ERROR+1
  28.  
  29. void printError (SRV_PROC *pSrvProc, CHAR* szErrorMsg);
  30. void printUsage (SRV_PROC *pSrvProc);
  31.  
  32. // It is highly recommended that all Microsoft« SQL Server (7.0 
  33. // and greater) extended stored procedure DLLs implement and export 
  34. // __GetXpVersion. For more information see SQL Server 
  35. // Books Online
  36. ULONG __GetXpVersion()
  37.  
  38. {
  39.     return ODS_VERSION;
  40. }
  41.  
  42.  
  43. SRVRETCODE xp_srv_paraminfo_sample
  44.     (
  45.     SRV_PROC* pSrvProc
  46.     )
  47.     {
  48.     char        acHeader[24];
  49.     BYTE        bType;
  50.     long        cbMaxLen;
  51.     long        cbActualLen;
  52.     PBYTE*      ppbData;
  53.     BOOL        fNull;
  54.     int         nParams;
  55.     int         nParam;
  56.     SRVRETCODE  rc = XP_NOERROR;
  57.  
  58. #ifdef _DEBUG
  59.     // In a debug build, look up the data type name for assistance.
  60.     DBCHAR*     pdbcDataType;
  61.     int         cbDataType;
  62. #endif
  63.  
  64.     // Count up the number of input parameters
  65.     nParams = srv_rpcparams(pSrvProc);
  66.     if (nParams == -1)
  67.         {
  68.         printUsage (pSrvProc);
  69.         return (XP_ERROR);
  70.         }
  71.     
  72.     // Build an array of data pointers for the input parameters.
  73.     ppbData = (PBYTE*) malloc(nParams * sizeof(PBYTE));
  74.     if (ppbData == NULL)
  75.         {
  76.         printError (pSrvProc, "Memory allocation error.");
  77.         return (XP_ERROR);
  78.         }
  79.     memset(ppbData, (int) NULL, nParams * sizeof(PBYTE));
  80.  
  81.     for (nParam = 0; nParam < nParams; nParam++)
  82.         {
  83.         // Use srv_paraminfo to get data type and length information. Ask
  84.         // for the data later using a non-null ppbData argument in a second
  85.         // srv_paraminfo call.
  86.         if (srv_paraminfo(pSrvProc, nParam+1, &bType, &cbMaxLen, &cbActualLen,
  87.             NULL, &fNull) == FAIL)
  88.             {
  89.             rc = XP_ERROR;
  90.             break;
  91.             }
  92.         
  93.         // Describe the paramter. The column header indicates whether
  94.         // the parameter is input or output.
  95.         sprintf(acHeader, "Parameter %d: %s", nParam+1,
  96.             ((srv_paramstatus(pSrvProc, nParam+1) & SRV_PARAMRETURN) ?
  97.             "Output" : "Input"));
  98.         srv_describe(pSrvProc, nParam+1, acHeader, SRV_NULLTERM, bType,
  99.             cbActualLen, bType, cbActualLen, NULL);
  100.  
  101.         // If there's data, then dynamically allocate memory and retrieve it.
  102.         if (fNull == 0)
  103.             {
  104.             ppbData[nParam] = malloc(cbActualLen);
  105.             if (ppbData[nParam] == NULL)
  106.                 {
  107.                 rc = XP_ERROR;
  108.                 break;
  109.                 }
  110.             if (srv_paraminfo(pSrvProc, nParam+1, &bType, &cbMaxLen,
  111.                 &cbActualLen, ppbData[nParam], &fNull) == FAIL)
  112.                 {
  113.                 rc = XP_ERROR;
  114.                 break;
  115.                 }
  116.             }
  117.  
  118. #ifdef _DEBUG
  119.         // A debugging aid. Get the name of the data type of the parameter.
  120.         pdbcDataType = srv_symbol(SRV_DATATYPE, (int) bType, &cbDataType);
  121. #endif
  122.  
  123.         // Set the column's data;
  124.         if (srv_setcoldata(pSrvProc, nParam+1, ppbData[nParam]) == FAIL)
  125.             {
  126.             rc = XP_ERROR;
  127.             break;
  128.             }
  129.         }
  130.  
  131.     // Send the row to the client.
  132.     if (rc == XP_NOERROR)
  133.         {
  134.         if (srv_sendrow(pSrvProc) == FAIL)
  135.             {
  136.             rc = XP_ERROR;
  137.             }
  138.         }
  139.  
  140.     // Free dynamically allocated memory.
  141.     for (nParam = 0; nParam < nParams; nParam++)
  142.         {
  143.         if (ppbData[nParam])
  144.             {
  145.             free(ppbData[nParam]);
  146.             }
  147.         }
  148.  
  149.     free(ppbData);
  150.  
  151.     // Indicate that we're done.
  152.     if (rc == XP_NOERROR)
  153.         {
  154.         srv_senddone(pSrvProc, (SRV_DONE_COUNT | SRV_DONE_MORE), 0, 1);
  155.         }
  156.     else if (rc == XP_ERROR)
  157.         {
  158.         printError (pSrvProc, "XP encountered an error.");
  159.         }
  160.  
  161.     return (rc);
  162.     }
  163.  
  164. // send szErrorMsg to client
  165. void printError (SRV_PROC *pSrvProc, CHAR* szErrorMsg)
  166.     {
  167.     srv_sendmsg(pSrvProc, SRV_MSG_ERROR, XP_ERROR, SRV_INFO, 1,
  168.             NULL, 0, (DBUSMALLINT) __LINE__, 
  169.             szErrorMsg,
  170.             SRV_NULLTERM);
  171.  
  172.     srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0);
  173.     }
  174.  
  175. // send XP usage info to client
  176. void printUsage (SRV_PROC *pSrvProc)
  177.     {
  178.     // usage: exec xp_srv_paraminfo_sample [@param1, [@param2 output],...]
  179.  
  180.     srv_sendmsg(pSrvProc, SRV_MSG_ERROR, XP_PARAM_ERROR, SRV_INFO, 1,
  181.             NULL, 0, (DBUSMALLINT) __LINE__, 
  182.             "usage: exec xp_srv_paraminfo_sample [@param1, [@param2 output],...]",
  183.             SRV_NULLTERM);
  184.     srv_senddone(pSrvProc, (SRV_DONE_ERROR | SRV_DONE_MORE), 0, 0);
  185.  
  186.     }
  187.