Sample SQLWindows SAL code to read in and parse a CSV file.

Function: LoadCustomerTable
    Description: Loads CUSTDATA.CSV into its 5 components,
                sTokens[0] - sTokens[4] and INSERTs this into the
                CUSTOMER table.
    Returns
        Boolean:
    Parameters
        Window Handle: hWndParent
    Static Variables
    Local variables
        File Handle: hFile
        Number: nComma
        String: sBuffer
        String: sTemp
        String: sStatus
        String: sTokens[*]
        Number: nToken
        ! Variables below only required for SAM_SqlError error processing
        String: sErr
        String: sErrMsg
        Sql Handle: hSqlError
        Number: nErr
        Number: nErrPos
    Actions
        Call SalWaitCursor( TRUE )
        Call SalStatusSetText( hWndParent, 'Loading CUSTOMER table' )
        !
        ! Reinitialize the data in the CUSTOMER table by first deleting what's
          there before loading in CUSTDATA.CSV data...
        When SqlError
            Call SqlExtractArgs( wParam, lParam, hSqlError, nErr, nErrPos )
            Call SqlGetErrorText( nErr, sErrMsg )
            Call SalNumberToStr( nErr , 0 , sTemp )
            If SalMessageBox( sTemp || ' - ' || sErrMsg || '. Quit?',
                    'SQL ERROR',
                     MB_YesNo | MB_IconQuestion | MB_DefButton2 ) = IDYES
                Call SalQuit()
        If NOT SqlPrepareAndExecute( hSqlDML, 'DELETE FROM customer' )
            Return FALSE
        If NOT SqlCommit( hSqlDML )
            Return FALSE
        !
        ! Open CUSTDATA.CSV for reading
        If NOT SalFileOpen( hFile, 'CUSTDATA.CSV', OF_Read | OF_Text )
            Call SalMessageBox( 'Open failed!', 'Error', MB_Ok | MB_IconStop )
            Return FALSE
        !
        ! Prepare the INSERT for the loop below - an array of strings can be
          used for the 5 VARCHAR columns - first is Number ID, though
          SQLBase/router will do datatype conversion from String --> Number.
        If NOT SqlPrepare( hSqlDML,
            'INSERT INTO customer( id, name, addr, city, state )
            VALUES( :sTokens[0], :sTokens[1], :sTokens[2], :sTokens[3],
                    :sTokens[4] )' )
            Return FALSE
        Loop FILE
            If NOT SalFileGetStr( hFile, sBuffer, 100  )
                Break
            If SalStrLength( sBuffer ) = 0
                Break
            !
            ! let the user know we're working...
            Call SalStatusGetText( hWndParent, sStatus, 100 )
            Call SalStatusSetText( hWndParent, sStatus || ' . ' )
            !
            Set nToken = 0
            Loop LINE
                If SalStrLength( sBuffer ) = 0
                    Break
                !
                ! get the next value
                Set nComma = SalStrScan( sBuffer, ',' )
                ! At the last token? (CUSTDATA.CSV file has no final comma).
                  If so, a -1 is returned from the SalStrScan() call
                If nComma = -1
                    ! yes, at the last token; just assign it directly
                    Set sTokens[nToken] = sBuffer
                    ! null sBuffer for the Break above
                    Set sBuffer = ''
                Else
                    ! no, so get the next token
                    Call SalStrMid( sBuffer, 0, nComma, sTokens[nToken] )
                !
                ! Check for a leading double quote = 34; this will be kept a
                  string
                Set sTemp = sTokens[nToken]
                If SalStrLop( sTemp ) = 34
                    ! Strip off leading double quote
                    Call SalStrLop( sTokens[nToken] )
                    ! Now, strip off trailing double quote
                    Call SalStrLeft( sTokens[nToken],
                    SalStrLength( sTokens[nToken] )-1, sTokens[nToken] )
                !
                ! And strip off current sTokens[nToken] from sBuffer
                Call SalStrRight( sBuffer, SalStrLength( sBuffer )-nComma-1,
                                sBuffer )
                Set nToken = nToken+1
                !
                When SqlError
                    Call SqlExtractArgs( wParam, lParam, hSqlError, nErr,
                                        nErrPos )
                    Call SqlGetErrorText( nErr, sErrMsg )
                    Call SalNumberToStr( nErr , 0 , sTemp )
                    If SalMessageBox( sTemp || ' - ' || sErrMsg || '. Quit?',
                          'SQL ERROR',
                          MB_YesNo | MB_IconQuestion | MB_DefButton2 ) = IDYES
                        Call SalQuit()
                If NOT SqlExecute( hSqlDML )
                    Return FALSE
            !
        Call SalFileClose( hFile )
        If NOT SqlCommit( hSqlDML )
            Return FALSE
        Call SalWaitCursor( FALSE )
        !
        Return TRUE
