home *** CD-ROM | disk | FTP | other *** search
/ Software Collection (I) / TOOLS.iso / b18 / 1.img / SQLUTILS.BA@ / SQLUTILS.bin
Encoding:
Text File  |  1992-09-15  |  8.2 KB  |  311 lines

  1.  
  2. 'SQLUTILS.BAS -- Utility fuctions for BASIC DB-LIBRARY.
  3.  
  4. 'Copyright (c) 1990 by Microsoft Corp.  All Rights Reserved.
  5.  
  6.  
  7. '$INCLUDE: 'sql.bi'
  8.  
  9. 'Type definition used by SqlGetTableInfo% and SqlSendQuery%.
  10. TYPE ColumnData
  11.     Name AS STRING * 30
  12.     Type AS INTEGER
  13.     Length AS LONG
  14.     ServerType AS STRING * 13
  15. END TYPE
  16.  
  17. 'Declaration of utility functions.
  18. DECLARE FUNCTION SqlOpenConnection& (Server$, LoginID$, Passwd$, Workstation$, Application$)
  19. DECLARE FUNCTION SqlGetTableInfo% (SqlConn&, Database$, Table$, Column() AS ColumnData, ColCount%)
  20. DECLARE FUNCTION SqlSendQuery% (SqlConn&, Query$, Column() AS ColumnData, Results() AS STRING, RowCount%, ColCount%)
  21. DECLARE FUNCTION SqlServType$ (SqlType%)
  22.  
  23. 'This function obtains, in a ColumnData array, the metadata for any single
  24. 'table from any database.  If the database name is blank, the current
  25. 'database is queried.
  26. '
  27. 'The array passed as a parameter must be dynamic.  Allocate the array in
  28. 'the calling procedure with the REDIM statement.
  29. '
  30. FUNCTION SqlGetTableInfo% (SqlConn&, Database$, Table$, Column() AS ColumnData, ColCount%)
  31.  
  32.     DIM ColumnNam(1 TO 255) AS STRING * 30
  33.     DIM ColumnTyp(1 TO 255) AS INTEGER
  34.     DIM ColumnLen(1 TO 255) AS LONG
  35.  
  36.     'Assemble SQL command string to send.
  37.     cmd$ = "SELECT col.name, col.type, col.length FROM "
  38.     IF Database$ <> "" THEN
  39.         sysobjs$ = Database$ + "..syscolumns col," + Database$ + "..sysobjects obj"
  40.     ELSE
  41.         sysobjs$ = "syscolumns col, sysobjects obj"
  42.     END IF
  43.     cmd$ = cmd$ + sysobjs$ + " WHERE obj.id = col.id and obj.name = '" + Table$ + "'"
  44.     
  45.     'Send command string to SQL Server.
  46.     IF SqlCmd%(SqlConn&, cmd$) = FAIL THEN
  47.         SqlGetTableInfo% = FAIL
  48.         EXIT FUNCTION
  49.     END IF
  50.     
  51.     IF SqlExec%(SqlConn&) = FAIL THEN
  52.         SqlGetTableInfo% = FAIL
  53.         EXIT FUNCTION
  54.     END IF
  55.  
  56.     'Read rows, storing metadata in arrays.
  57.     Result% = SqlResults%(SqlConn&)
  58.     Result% = SqlNextRow%(SqlConn&)
  59.     ColCount% = 0
  60.     DO UNTIL Result% = NO.MORE.ROWS
  61.         IF Result% = FAIL THEN
  62.             SqlGetTableInfo% = FAIL
  63.             EXIT FUNCTION
  64.         END IF
  65.  
  66.         IF Result% = BUF.FULL THEN
  67.             CALL SqlClrBuf(SqlConn&, 1)
  68.         ELSE
  69.             ColCount% = ColCount% + 1
  70.             ColumnNam(ColCount%) = SqlData$(SqlConn&, 1)
  71.             ColumnTyp(ColCount%) = VAL(SqlData$(SqlConn&, 2))
  72.             ColumnLen(ColCount%) = VAL(SqlData$(SqlConn&, 3))
  73.         END IF
  74.  
  75.         Result% = SqlNextRow%(SqlConn&)
  76.     LOOP
  77.  
  78.     IF ColCount% = 0 THEN
  79.         SqlGetTableInfo% = FAIL
  80.         EXIT FUNCTION
  81.     END IF
  82.  
  83.     'Transfer results into ColumnData array.
  84.     REDIM Column(1 TO ColCount%) AS ColumnData
  85.     FOR c% = 1 TO ColCount%
  86.         Column(c%).Name = ColumnNam(c%)
  87.         Column(c%).Type = ColumnTyp(c%)
  88.         Column(c%).Length = ColumnLen(c%)
  89.         Column(c%).ServerType = SqlServType$(ColumnTyp(c%))
  90.     NEXT c%
  91.  
  92.     SqlGetTableInfo% = SUCCEED%
  93.  
  94. END FUNCTION
  95.  
  96. 'This function fills in a login record and opens a SQL Server connection.
  97. '
  98. FUNCTION SqlOpenConnection& (Server$, LoginID$, Passwd$, Workstation$, Application$)
  99.  
  100.     'Obtain a login record and fill in.
  101.     Login& = SqlLogin&
  102.     IF Login& = 0& THEN
  103.         SqlOpenConnection& = 0&
  104.         EXIT FUNCTION
  105.     END IF
  106.  
  107.     IF LoginID$ <> "" THEN
  108.         IF SqlSetLUser%(Login&, LoginID$) = FAIL THEN
  109.             CALL SqlFreeLogin(Login&)
  110.             SqlOpenConnection& = 0&
  111.             EXIT FUNCTION
  112.         END IF
  113.     END IF
  114.  
  115.     IF Passwd$ <> "" THEN
  116.         IF SqlSetLPwd%(Login&, Passwd$) = FAIL THEN
  117.             CALL SqlFreeLogin(Login&)
  118.             SqlOpenConnection& = 0&
  119.             EXIT FUNCTION
  120.         END IF
  121.     END IF
  122.  
  123.     IF Workstation$ <> "" THEN
  124.         IF SqlSetLHost%(Login&, Workstation$) = FAIL THEN
  125.             CALL SqlFreeLogin(Login&)
  126.             SqlOpenConnection& = 0&
  127.             EXIT FUNCTION
  128.         END IF
  129.     END IF
  130.  
  131.     IF Application$ <> "" THEN
  132.         IF SqlSetLApp%(Login&, Application$) = FAIL THEN
  133.             CALL SqlFreeLogin(Login&)
  134.             SqlOpenConnection& = 0&
  135.             EXIT FUNCTION
  136.         END IF
  137.     END IF
  138.  
  139.     'Open connection and free login record.
  140.     SqlOpenConnection& = SqlOpen&(Login&, Server$)
  141.     CALL SqlFreeLogin(Login&)
  142.  
  143. END FUNCTION
  144.  
  145. 'This function sends a single query and obtains the results in a
  146. 'two-dimensional array.  The metadata (column names, lengths, and
  147. 'datatypes) for the result columns is returned in a ColumnData array.
  148. '
  149. 'If more rows are returned than can be stored in the array, the
  150. 'function returns MORE.ROWS (-1).  To obtain the remaining rows,
  151. 'call the function repeatedly with an empty Query$.  If all rows
  152. 'are returned, the function returns SUCCEED (1).
  153. '
  154. 'The two arrays passed as parameters must be dynamic.  Allocate the arrays
  155. 'in the calling procedure with the REDIM statement.
  156. '
  157. FUNCTION SqlSendQuery% (SqlConn&, Query$, Column() AS ColumnData, Results() AS STRING, RowCount%, ColCount%)
  158.  
  159.     'Send the query to the server unless Query$ is empty.
  160.     IF Query$ <> "" THEN
  161.         Result% = SqlCancel%(SqlConn&)
  162.  
  163.         IF SqlCmd%(SqlConn&, Query$) = FAIL THEN
  164.             SqlSendQuery% = FAIL
  165.             EXIT FUNCTION
  166.         END IF
  167.  
  168.         IF SqlExec%(SqlConn&) = FAIL THEN
  169.             SqlSendQuery% = FAIL
  170.             EXIT FUNCTION
  171.         END IF
  172.  
  173.         Result% = SqlResults%(SqlConn&)
  174.     END IF
  175.  
  176.     'Store the metadata for the results in a ColumnData array.
  177.     RowCount% = 0
  178.     ColCount% = SqlNumCols%(SqlConn&)
  179.     IF ColCount% = 0 THEN
  180.         Result% = SqlCancel%(SqlConn&)
  181.         SqlSendQuery% = SUCCEED
  182.         EXIT FUNCTION
  183.     END IF
  184.     REDIM Column(1 TO ColCount%) AS ColumnData
  185.     RowLen& = 0
  186.     FOR c% = 1 TO ColCount%
  187.         Column(c%).Name = SqlColName$(SqlConn&, c%)
  188.         Column(c%).Type = SqlColType%(SqlConn&, c%)
  189.         Column(c%).Length = SqlColLen&(SqlConn&, c%)
  190.         Column(c%).ServerType = SqlServType$(Column(c%).Type)
  191.  
  192.         'Add possible length of strings to RowLen&.
  193.         SELECT CASE Column(c%).Type
  194.             CASE SQLINT1: RowLen& = RowLen& + 3
  195.             CASE SQLINT2: RowLen& = RowLen& + 6
  196.             CASE SQLINT4: RowLen& = RowLen& + 10
  197.             CASE SQLMONEY, SQLFLT8, SQLDATETIME
  198.                 RowLen& = RowLen& + 20
  199.             CASE ELSE: RowLen& = RowLen& + Column(c%).Length
  200.         END SELECT
  201.     NEXT c%
  202.  
  203.     'Determine maximum number of rows that fit in memory.
  204.     FreeMem& = FRE(Results(LBOUND(Results, 1), LBOUND(Results, 2)))
  205.     IF FreeMem& > (FRE(-1) \ 2) THEN FreeMem& = FRE(-1) \ 2
  206.     MaxRows% = (FreeMem& - 1024) \ (6 * ColCount% + RowLen&)
  207.  
  208.     StackSize% = 8192      'You must set this to stack size if not 8K.
  209.     Max2% = (STACK - StackSize% - 32) \ (ColCount% * 4)
  210.     IF MaxRows% > Max2% THEN MaxRows% = Max2%
  211.  
  212.     IF MaxRows% = 0 THEN
  213.         SqlSendQuery% = MORE.ROWS
  214.         EXIT FUNCTION
  215.     END IF
  216.  
  217.     REDIM Buffer(1 TO MaxRows%, 1 TO ColCount%) AS STRING
  218.  
  219.     'Read the resulting rows into the buffer.
  220.     Result% = SqlNextRow%(SqlConn&)
  221.     DO UNTIL Result% = NO.MORE.ROWS
  222.  
  223.         IF Result% = FAIL THEN
  224.             SqlSendQuery% = FAIL
  225.             EXIT FUNCTION
  226.         END IF
  227.  
  228.         IF Result% = BUF.FULL THEN
  229.             CALL SqlClrBuf(SqlConn&, 1)
  230.         ELSE
  231.             RowCount% = RowCount% + 1
  232.             FOR c% = 1 TO ColCount%
  233.                 Buffer(RowCount%, c%) = SqlData$(SqlConn&, c%)
  234.             NEXT c%
  235.         END IF
  236.  
  237.         IF RowCount% = MaxRows% THEN EXIT DO
  238.         Result% = SqlNextRow%(SqlConn&)
  239.     LOOP
  240.  
  241.     IF Result% = NO.MORE.ROWS THEN
  242.         Result% = SqlCancel%(SqlConn&)
  243.         SqlSendQuery% = SUCCEED
  244.     ELSE
  245.         SqlSendQuery% = MORE.ROWS
  246.     END IF
  247.  
  248.     IF RowCount% = 0 THEN EXIT FUNCTION
  249.  
  250.     'Transfer results from buffer.
  251.     REDIM Results(1 TO RowCount%, 1 TO ColCount%) AS STRING
  252.     FOR r% = 1 TO RowCount%
  253.         FOR c% = 1 TO ColCount%
  254.             Results(r%, c%) = Buffer(r%, c%)
  255.         NEXT c%
  256.     NEXT r%
  257. END FUNCTION
  258.  
  259. 'This function takes a datatype value and returns the SQL Server
  260. 'datatype name.
  261. '
  262. FUNCTION SqlServType$ (SqlType%)
  263.     SELECT CASE SqlType%
  264.         CASE SQLCHAR
  265.             SqlServType$ = "char"
  266.         CASE SQLVARCHAR
  267.             SqlServType$ = "varchar"
  268.         CASE SQLTEXT
  269.             SqlServType$ = "text"
  270.         CASE SQLMONEY
  271.             SqlServType$ = "money"
  272.         CASE SQLMONEYN
  273.             SqlServType$ = "money-null"
  274.         CASE SQLDATETIME
  275.             SqlServType$ = "datetime"
  276.         CASE SQLDATETIMN
  277.             SqlServType$ = "datetime-null"
  278.         CASE SQLFLT8
  279.             SqlServType$ = "float"
  280.         CASE SQLFLTN
  281.             SqlServType$ = "float-null"
  282.         CASE SQLINTN
  283.             SqlServType$ = "integer-null"
  284.         CASE SQLINT1
  285.             SqlServType$ = "tinyint"
  286.         CASE SQLINT2
  287.             SqlServType$ = "smallint"
  288.         CASE SQLINT4
  289.             SqlServType$ = "int"
  290.         CASE SQLIMAGE
  291.             SqlServType$ = "image"
  292.         CASE SQLBINARY
  293.             SqlServType$ = "binary"
  294.         CASE SQLVARBINARY
  295.             SqlServType$ = "varbinary"
  296.         CASE SQLBIT
  297.             SqlServType$ = "bit"
  298.         CASE SQLAOPSUM
  299.             SqlServType$ = "sum"
  300.         CASE SQLAOPAVG
  301.             SqlServType$ = "avg"
  302.         CASE SQLAOPMIN
  303.             SqlServType$ = "min"
  304.         CASE SQLAOPMAX
  305.             SqlServType$ = "max"
  306.         CASE SQLAOPCOUNT
  307.             SqlServType$ = "count"
  308.     END SELECT
  309. END FUNCTION
  310.  
  311.