none
Soucis T-SQL avec SQLNCLI10 RRS feed

  • Question

  • Bonjour,

    Je viens de commencer le développement d'une application utilisant l'API SQL Native Client 10.

    Pour la plupart de mes requêtes (Insert/Delete/Update ...) l'utilisation de SQLExecDirect suffit largement à mes besoins.

    J'ai cependant un problème avec un code T-SQL.

    J'ai testé le code sous SQL Server Management Studio, mon code fait parfaitement la tâche qui lui est demandée (itération sur les tables et importe des données inter-bases avec conversion de type (cast).

    Cependant, avec SQLExecDirect il s'arrête à la première itération et ne traite pas les tables suivantes.

    Ma requêtes SQL : 

    Use BaseUnique;
    SELECT DISTINCT
            [t].[name] [TableName]
    INTO
            [BaseUnique].[dbo].[TEMP_TN]
    FROM
            [BaseUnique].[sys].[tables] [t]
    WHERE
            t.[name] LIKE 'OXYG_%';
    ALTER TABLE [BaseUnique].[dbo].[TEMP_TN]
            ADD [OX_COMPTEUR] BIGINT  NOT NULL IDENTITY(1, 1) PRIMARY KEY;
    DECLARE @base nvarchar(10)
    SET @base = 'Test'
    DECLARE @iot INT, @iotMax INT
    SET @iot = 1
    SET @iotMax = (SELECT COUNT(*) FROM [BaseUnique].[dbo].[TEMP_TN])
    DECLARE @tbl sysname
    WHILE @iot <= @iotMax
    BEGIN
            --
            SELECT @tbl = [TableName] FROM [BaseUnique].[dbo].[TEMP_TN]
                    WHERE [OX_COMPTEUR] = @iot;
            --
    
            SELECT
                    [s].[name] [SchemaName]
                    , [c].[name] [ColumnName]
                    , [c].[system_type_id] [ColumnTypeID]
            INTO
                    [BaseUnique].[dbo].[TEMP_ALL]
            FROM
                    [BaseUnique].[sys].[columns] [c]
                    INNER JOIN [BaseUnique].[sys].[tables] [t]
                            ON [c].[object_id] = [t].[object_id]
                    INNER JOIN [BaseUnique].[sys].[schemas] [s]
                            ON [t].[schema_id] = [s].[schema_id]
            WHERE
                    [t].[name] = @tbl
            AND
                    [c].[name] <> 'OX_COMPTEUR'
            ;
            ALTER TABLE [BaseUnique].[dbo].[TEMP_ALL]
                    ADD [OX_COMPTEUR] BIGINT  NOT NULL IDENTITY(1, 1) PRIMARY KEY;
            --
            DECLARE @ioc int, @iocMax int
            SET @ioc = 1
            SET @iocMax = (SELECT COUNT(*) FROM [BaseUnique].[dbo].[TEMP_ALL])
            DECLARE @sch sysname, @col sysname, @typ tinyint
            DECLARE @query nvarchar(max)
            SET @query = 'INSERT INTO [BaseUnique].[dbo].'+@tbl+' SELECT'
            WHILE @ioc <= @iocMax
            BEGIN
                    SELECT @sch = [SchemaName]
                            , @col = [ColumnName]
                            , @typ = [ColumnTypeID]
                    FROM
                            [BaseUnique].[dbo].[TEMP_ALL]
                    WHERE
                            [OX_COMPTEUR] = @ioc
                    ;
                    ------------
                    -- Prefix --
                    ------------
                    IF (@ioc <> 1)
                            SET @query = @query+' ,'
                    ELSE
                            SET @query = @query+' '
                    -------------
                    -- Requete --
                    -------------
                    IF (@typ = 167)
                    BEGIN
                            SET @query = @query+'['+@base+'].['+@sch+'].['+@tbl+'].['+@col+']'
                    END
                    ELSE IF (@typ = 62)
                    BEGIN
                            SET @query = @query+'CAST(
                                    REPLACE(
                                            REPLACE(
                                                    ['+@base+'].['+@sch+'].['+@tbl+'].['+@col+']'+', '','', ''.''
                                            ), '' '', ''''
                                    ) AS float
                            )'
                    END
                    ELSE IF (@typ = 56)
                    BEGIN
                            SET @query = @query+'CAST(['+@base+'].['+@sch+'].['+@tbl+'].['+@col+'] AS int)'
                    END
                    ELSE IF (@typ = 40)
                    BEGIN
                            SET @query = @query+'CAST(['+@base+'].['+@sch+'].['+@tbl+'].['+@col+'] AS date)'
                    END
                    ELSE
                    BEGIN
                            SET @query = @query+'['+@base+'].['+@sch+'].['+@tbl+'].['+@col+']'
                    END
                    --
                    SET @ioc = @ioc + 1
            END
            -- EXECUTE QUERY STRING
            SET @query = @query+' FROM ['+@base+'].['+@sch+'].['+@tbl+']'
            select @query
    
            EXEC sp_executesql @query
            DROP TABLE [BaseUnique].[dbo].[TEMP_ALL]
            --
            SET @iot = @iot + 1
    END
    DROP TABLE [BaseUnique].[dbo].[TEMP_TN];

    Mon utilisation de SQLExecDirect

    // Connexion
    SQLHelper::SQLHelper(void) {
    		stringstream sConnString;
    		sConnString << "Driver={SQL Server Native Client 10.0};" 
    			<< "Server=" << configSingleton::getInstance().BDDServer() << ";" 
    			<< "UID=" << configSingleton::getInstance().BDDUserName() << ";" 
    			<< "PWD=" << configSingleton::getInstance().BDDPassword() << ";"
    			<< "Database=" << configSingleton::getInstance().BDDBase() << ";";
    	RETCODE ret;
    	ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv); // Handle environement
    	test_retcode(ret, "Probleme de création de l'handle de l'environement", hEnv);
    	ret = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0); // Version odbc
    	test_retcode(ret, "Probleme lors de l'attribution de la version ODBC3", hEnv);
    
    	ret = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDBCCount); // Handle connexion
    	test_retcode(ret, "Probleme de création de l'handle de connexion", hDBCCount);
    	ret = SQLSetConnectAttr(hDBCCount, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER); // Attribut de connexion
    	test_retcode(ret, "Probleme d'atributs sur l'handle de connexion", hDBCCount);
    	ret = SQLDriverConnect(hDBCCount, NULL, (SQLTCHAR *) sConnString.str().c_str(), SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
    	test_retcode(ret, "Probleme de connexion", hDBCCount);
    }
    // Execution
    void SQLHelper::returnlessQuery(string const& query) {
    	SQLHANDLE hStmtCount;
    	RETCODE ret;
    
    	ret = SQLAllocHandle(SQL_HANDLE_STMT, hDBCCount, &hStmtCount);
    	test_retcode(ret, "Probleme de creation d'handler de transaction", hStmtCount);
    
    	ret = SQLExecDirect(hStmtCount, (SQLCHAR *) query.c_str() , SQL_NTS);
    	test_retcode(ret, "Probleme d'execution de la requete : \n"+query+"\n", hStmtCount);
    
    	ret = SQLEndTran(SQL_HANDLE_DBC, hDBCCount, SQL_COMMIT);
    	test_retcode(ret, "Probleme de COMMIT", hStmtCount);
    	return;
    }
    // Erreurs
    bool SQLHelper::test_retcode( RETCODE const& my_code, string const& noticeMsg, SQLHANDLE const& hStmtCount) const {
    	if ( my_code == SQL_SUCCESS_WITH_INFO || my_code == SQL_SUCCESS ) {
    	} else {
    		string err_msg;
    		err_msg.reserve(255);
    		SQLCHAR state[6];
    		SQLINTEGER error;
    		SQLINTEGER output_length;
    		int sql_state = SQLGetDiagRec( SQL_HANDLE_STMT, hStmtCount, 1, state, &error, (SQLCHAR*) err_msg.data(), (SQLINTEGER) 255, (SQLSMALLINT*) &output_length );
    		logSystem::log(err_msg, noticeMsg);
    	}
    	return ( my_code == SQL_SUCCESS_WITH_INFO || my_code == SQL_SUCCESS );
    }

    Merci d'avance pour votre aide.

    Nacrotic


    • Modifié Nacrotic mardi 21 janvier 2014 10:56 Correction typo
    mardi 21 janvier 2014 10:56