Quantcast
Channel: Teradata Developer Exchange - Blog activity for NetFx's blog
Viewing all 56 articles
Browse latest View live

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by vivek_vinayan

$
0
0

I just cancelled the execution and I am not installing the linked server to TD. 
But now the server is extremely slow and sometimes give error for not executing. I am not able to run any other packages on the SSIS. Please help.
 
Regards
Vivek


DbProviderFactories Demystified - comment by shahpoo

$
0
0

I am running on target framework as ".NET framework 4 client Profile". and As per code provided I updated my app.config file with <dbProviderFactories> code with set invariant as "Teradata.Client.Provider.Unique".
Now my Form1.cs file has code as follow:
DbProviderFactory factory = DbProviderFactories.GetFactory("Terada.Client.Provider"); 
And that thows an error on runtime "Unable to find the requested .Net framework Data Provider. It may not be installed."
I have installed reference to "Teradata.Client.Provider.dll" version 14.10.0.0
Can you please help me here to resolve my issue.
Thanks,
 

DbProviderFactories Demystified - comment by NetFx

$
0
0

You must use the Invariant name in the App.Config file. That is GetFactory("Teradata.Client.Provider.Unique") if the entry in App.config file has the "Teradata.Client.Provider.Unique" invariant name.

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by david.pillow

$
0
0

Is it possible to set up a SQL Server linked server using the .net Framework Provider for Teradata rather than going via ODBC?
The reason for asking is that the .net provider is significantly faster than ODBC when used in SSIS and I want to harness this power via a linked server.
The option to select '.net Framework Provider for Teradata' is not provided when setting up the linked server using the SQL Server Management Studio gui.  Is it possible to manuall add the linked server, for instance doing something like the following:

    exec sp_addlinkedserver    @server=ERNET, @srvproduct='Teradata',

                               @provider='???????', 

                               @datasrc='172.29.232.143' 

 

If so - what is the value for ??????? (I've tried 'TDOLEDB.1' but I get the following message: 'cannot create an instance of OLE DB provider "TDOLEDB.1" for linked server "ERNET". (Microsoft SQL Server, Error 7302)) and does @srvproduct need to be defined?  I'm using SQL Server 2014.

Thank you

David

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by NetFx

$
0
0

To my knowledge SQL Server Linked Server requires an OLE DB Provider (e.g. Microsoft OLE DB Provider for ODBC). So the answer is no, you cannot use the .NET Data Provider for Teradata to create a Linked Server from SQL Server to the Teradata Database.

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by Kiran.g

$
0
0

Hi All,
I Followed the above steps everything worked fine until the last step while creating Linked server in SQL Server, I am getting the error 

Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "TDTEST".

OLE DB provider "MSDASQL" for linked server "TDTEST" returned message "[Microsoft][ODBC Driver Manager] Driver's SQLAllocHandle on SQL_HANDLE_ENV failed". (Microsoft SQL Server, Error: 7303)

 

Can anyone please help me in  solving this problem?

 

Thanks,

Kiran

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by comtest

$
0
0

jepatte: Thanks for instruction and patience, your suggestion works as a charm! basically after install the odbc driver, you have to reboot your server before the msdasql work in link server - 20160216

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by DMaheshwari80

$
0
0

We are facing the same error as Kiran. Can you please let us know how this was resolved?
 
Cannot initialize the data source object of OLE DB provider "MSDASQL" for linked server "XYZ".
OLE DB provider "MSDASQL" for linked server "XYZ" returned message "[Microsoft][ODBC Driver Manager] Driver's SQLAllocHandle on SQL_HANDLE_ENV failed". (Microsoft SQL Server, Error: 7303)


.NET Data Provider for Teradata Asynchronous Operations - blog entry by NetFx

$
0
0

.NET Framework has a very broad support for Asynchronous operations including a well defined Asynchronous Programming Model. All asynchronous operations are started by invoking a Begin method; later a corresponding End method is invoked to retrieve the result. .NET Application can use three different techniques to rendezvous with the asynchronous operation: a) Callback Method b) Poll for status and c) Wait on a thread synchronization handle. For Example FileStream class has BeginRead/EndRead methods and delegates have BeginInvoke/EndInvoke methods. For additional information about Asynchronous Programming and Patterns refer to:

MSDN: Asynchronous Programming Design Patterns

ADO.NET 2.0 specification defines three methods to execute SQL queries: 

  • ExecuteReader: returns result sets with one or more rows.
  • ExecuteScalar: result in a scalar value like Int32.
  • ExecuteNonQuery: returns number of rows affected.

These methods are part of DbCommand class in System.Data.Common namespace. These methods are synchronous; that is the executing thread is I/O bound because it is waiting for a response from Teradata database. Unfortunately DbCommand does not define Asynchronous Execution methods. However applications can call these synchronous methods asynchronously using a delegate. Code snippet below shows how to invoke ExecuteNonQuery asynchronously:
 

internal class AsyncCommand
{
    private delegate Int32 AsyncExecuteNonQuery();
        
    public AsyncCommand(String connectionString)
    {
        _asyncExecuteNonQuery = new AsyncExecuteNonQuery(_command.ExecuteNonQuery);
    }

    public void AsyncExecuteCommand(String sqlText)
    {
        _command.CommandText = sqlText;
        _asyncResult = _asyncExecuteNonQuery.BeginInvoke(null, null);
    }

    public Nullable<Int32> AffectedRows
    {
        get
        {
            if (_asyncResult != null)
            {
                Int32 result = _asyncExecuteNonQuery.EndInvoke(_asyncResult);               
            }
            else
            {
                return null;
            }
        }
    }
}

The AsyncExecuteNonQuery.BeginInvoke method shown above will dispatch a thread-pool thread to execute the DbCommand.ExecuteNonQuery method. In other words, the task identified by the delegate, in this case ExecuteNonQuery, is performed by another thread synchronously. For example an application executing 10 commands across 10 connections will result in 10 threads. The Performance Monitor graph below shows that number of available worker threads in the thread-pool decrease as each DbCommand.ExecuteNonQuery is invoked through a delegate. Later the threads are returned to the pool.

This graph must raise some alarms. That is applications servers will have scalability issues as the number of connections and users increase overtime.

See MSDN: Asynchronous Programming Using Delegates for additional information about calling Synchronous methods asynchronously.

.NET Data Provider for Teradata solves this scalability issue by introducing 4 new methods for asynchronous operations corresponding to two of the three Execute methods described above. The application's thread of execution is never I/O bound and .NET Data Provider for Teradata does not use one thread for each SQL Command. The code snippet below shows how to take advantage of TdCommand class Asynchronous methods:
 

internal class AsyncTdCommand
{
    public AsyncTdCommand(String connectionString)
    {
    }
 
    public void AsyncExecuteCommand(String sqlText)
    {
        _command.CommandText = sqlText;
        _asyncResult = _command.BeginExecuteNonQuery();
    }

    public Nullable<Int32> AffectedRows
    {
        get
        {
            if (_asyncResult != null)
            {
                Int32 result = _command.EndExecuteNonQuery(_asyncResult);
            }
            else
            {
                return null;
            }
        }
    }
}

 

TdCommand class asynchronous methods are highly scalable. For example an application executing 10 commands across 10 connections will only utilize one I/O thread for very short amount time . The Performance Monitor graph below shows that the number of available worker threads never decrease and one I/O thread is used for very short amount time.

In summary there are lots of scenarios where the Asynchronous feature of the .NET Data Provider for Teradata is very beneficial. For example

  • Use it in ASP.NET Asynchronous Pages to create very highly scalable applications.
  • Use it to execute two or more SQL commands simultaneously across two or more connections. There are scenarios where a multi-statement requests cannot be used; for example when one SQL command executes in half the time.
  •  Use it to execute background database commands in Windows Forms applications.

Little known Secret about Microsoft BI Tools and Teradata - blog entry by NetFx

$
0
0

Microsoft and Teradata worked together last year to integrate SQL Server Reporting, Analysis and Integration Services with Teradata Database. Some MSDN links that provide additional information:

Using SQL Server 2008 Reporting Services with the.NET Framework Data Provider for Teradata

SQL Server 2005: Configuring Reporting Services for Teradata-based Report Models

How to: Retrieve Data from a Teradata Data Source

Microsoft Connectors for Teradata by Attunity

Whitepaper - Improve your OLAP Environment with Microsoft and Teradata

ISV: Teradata

SQL Server Reporting Services connectivity to Teradata was built / linked with .NET Data Provider for Teradata version 12.0. Therefore please install the Publisher Policy assemblies for .NET Data Provider for Teradata to redirect to more recent versions of the .NET Data Provider for Teradata. For example you must install the publisher policy assemblies if you decide to install .NET Data Provider for Teradata version 13.0 instead of version 12.0.

Microsoft Visual Studio Hot Fixes for .NET Data Provider - blog entry by NetFx

$
0
0

Microsoft Visual Studio DataSet designer generates code (C#/VB.NET) to read data from a .NET Data Provider data source or apply changes to the data source. DataSet designer generates parameterized queries and sets the properties of DbParameter object to the corresponding column data type attributes. For example it sets DbParameter.DbType to DbType.String or DbType.Decimal. It also sets the DbParameter.Size to the column size which is the maximum number of characters for Char/VarChar columns.

However DataSet designer fails to set the Precision and Scale properties for the following data types:

  • Decimal
  • Time
  • Time with Time Zone
  • TimeStamp
  • TimeStamp With Time Zone
  • Interval Day-To-Second Data Type

This will result in loss of precision in some cases. For example .NET Data Provider for Teradata will truncate the sub-seconds for Time or TimeStamp data types.

Microsoft released two hot-fix for this issue; one hot-fix is for .NET Framework 2.0 SP1 and the other is applicable to .NET Framework 2.0 SP2.

http://support.microsoft.com/kb/958252

http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=958252&kbln=en-us

This hot-fix sets the Precision and Scale for Decimal Data Type automatically; but it does not set the precision and scale for DateTime and Intervals data types automatically. You must use the Parameter Collection Editor to set the precision and scale manually.

Ignore ancestor settings: 
0
Apply supersede status to children: 
0

DbProviderFactories Demystified - blog entry by NetFx

$
0
0

In this BLOG I will describe how to register a .NET Data Provider with the ADO.NET   DbProviderFactories Class.

System.Data.Common Namespace defines a set of abstract classes that are implemented by all .NET Data Providers. The intent is to provide a Data Source/Provider agnostic way of accessing data. Provider agnostic applications do not have direct references to ADO.NET Data Provider assemblies and it is the job of DbProviderFactories class to load the requested .NET Data Provider and return a concrete class known as DbProviderFactory. DbProviderFactory serves as the Factory for DbConnection, DbCommand and other ADO.NET  objects. For example the sample code shown below will load .NET Data Provider for Teradata assembly using the invariant name Teradata.Client.Provider:

 

class TestConsole
{
    static void Main(string[] args)
    {
        // DbProviderFactories loads "Teradata.Client.Provider.dll" assembly using 
        DbProviderFactory factory = DbProviderFactories.GetFactory("Teradata.Client.Provider");

        // DbProviderFactory creates a TdConnection class.
        using (DbConnection cn = factory.CreateConnection())
        {
            // DbProviderFactory creates a TdConnectionStringBuilder class.
            DbConnectionStringBuilder conStrBuilder = factory.CreateConnectionStringBuilder();
            conStrBuilder["Data Source"] = @"System1.myCorp.com";
            conStrBuilder["User Id"] = @"Alex";
            conStrBuilder["Password"] = @"myPassword";

            cn.ConnectionString = conStrBuilder.ConnectionString;
            cn.Open();

            // DbProviderFactory creates a TdCommand class.
            DbCommand cmd = factory.CreateCommand();
            cmd.Connection = cn;
            cmd.CommandText = @"SELECT DATE";

            Console.WriteLine("System Date: {0}", cmd.ExecuteScalar());
        }
    }
}

 

The mystery is how DbProviderFactories correlates an Invariant Name with a Provider Factory class (derived from DbProviderFactory class) and the corresponding assembly. DbProviderFactories simply reads the information from the configuration context/files (Machine.Config, App.Config ...).

NOTE: The overall concept of .NET Framework Configuration framework/files is outside of the scope of this blog. For additional information refer to Cracking the Mysteries of .NET 2.0 Configuration article by Jon Rista.

DbProviderFactories will read the System.Data section of the configuration context. For example .NET Framework 2.0 Machine.Config (located in %SystemRoot%\Microsoft.NET\Framework\v2.0.50727\CONFIG and %SystemRoot%\Microsoft.NET\Framework64\v2.0.50727\CONFIG ) usually has the following System.Data section:

<system.data>
  <DbProviderFactories>
     <add name="Odbc Data Provider" invariant="System.Data.Odbc" description=".Net Framework Data Provider for Odbc"         type="System.Data.Odbc.OdbcFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add name="OleDb Data Provider" invariant="System.Data.OleDb"         description=".Net Framework Data Provider for OleDb" 
         type="System.Data.OleDb.OleDbFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add name="OracleClient Data Provider" invariant="System.Data.OracleClient"         description=".Net Framework Data Provider for Oracle" 
         type="System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <add name="SqlClient Data Provider" invariant="System.Data.SqlClient"         description=".Net Framework Data Provider for SqlServer" 
         type="System.Data.SqlClient.SqlClientFactory, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </DbProviderFactories>
</system.data>

 

The invariant attribute is a version independent name (e.g. System.Data.Odbc) and type attribute is a fully qualified Type name for the associated DbProviderFactory class.  Type name has two parts namely class name (System.Data.Odbc.OdbcFactory) and the Strong Assembly Name (System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"). At this point DbProviderFactories simply invokes Type.GetType   to load Assembly and create an instance of the Type.

This means that you can simply add your favorite .NET Data Provider to the configuration context. For example add the following XML element for .NET Data Provider for Teradata version 13.1.0.4:

 

<add name=".NET Data Provider for Teradata" invariant="Teradata.Client.Provider"    description=".NET Framework Data Provider for Teradata" 
    type="Teradata.Client.Provider.TdFactory, Teradata.Client.Provider, Version=13.1.0.4, Culture=neutral, PublicKeyToken=76b417ee2e04956c" />

 

.NET Data Provider for Teradata installation automatically modifies the .NET Framework 2.0 Machine.Config files (32-bit and 64-bit). Note the emphasizes on .NET Framework 2.0; .NET Framework 4.0 has a separate set of Machine.Config files which you can manually update or alternatively you can invoke InstallUtil.exe version 4.0 as described below to update .NET Framework 4.0 Machine.config file:

  1. Open a command with elevated permissions (Run as Administrator).
  2. Execute 32-bit InstallUtil version 4.0 to update the 32-bit Machine.config  with a reference to .NET Data Provider for Teradata: %SystemRoot%\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe "C:\Program Files (x86)\Teradata\NET Data Provider for Teradata\13.01.00\bin\Teradata.Client.Provider.dll"
  3. Execute 64-bit InstallUtil version 4.0 to update the 64-bit machine.config file. 

 

There is yet another alternative; App.Config file can simply have a "System.Data" section which is merged with the System.Data section of the Machine.config file as shown below:

<?xml version="1.0"?>
<configuration>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>

  <system.data>
    <DbProviderFactories>
      <add name=".NET Data Provider for Teradata" invariant="Teradata.Client.Provider.Unique"        description=".NET Framework Data Provider for Teradata" 
        type="Teradata.Client.Provider.TdFactory, Teradata.Client.Provider, Version=13.1.0.4, Culture=neutral, PublicKeyToken=76b417ee2e04956c" />
    </DbProviderFactories>
  </system.data>

</configuration>

 

Note that the Data Provider Invariant name must be unique after the content of machine.config and app.config are merged into the configuration context.

Ignore ancestor settings: 
0
Apply supersede status to children: 
0

Specify Data Source with Fully Qualified Domain Name - blog entry by NetFx

$
0
0

Data Source with Fully Qualified Domain Name can speed up logons plagued with slow "Name to IP-Address resolution". 

Applications / users must specify a Data Source (a.k.a. TDPID, DbcName, Server or System Name) in order to connect to Teradata Database. For example SQL Assistant 13.0 prompts for Connection Information:

 

 

In this example the Server field is set to TDPID; however a better choice for Server name is TDPID.myCorp.com. In other words we recommend appending Domain Name to the Server Name (Note: Server Name in SQL Assistant corresponds to TdConnectionStringBuilder.DataSource property in .NET Data Provider for Teradata).

A Teradata Database system can have more than one Communication Processor (COP). All COPs are assigned an IP-Address and registered in DNS with a sequential numbering convention; for example sysNameCOP1,  sysNameCOP2, … and sysNameCOPn.   .NET Data Provider for Teradata will discover/detect all Communication Processors (or Gateways) during the first logon. Data Provider relies on the COP naming/numbering convention; it starts by appending COP1  to the name (e.g. sysName) followed by COP2, COP3, … and COPn until a Host Not Found exception is thrown. Teradata has used the "Cop Discovery" process for years and it usually performs very well. The COP Discovery overall performance is dependent on the performance of Name to IP-Address resolution. 

The process of resolving a Name to an IP Address on Microsoft Windows platform is described in Host Name Resolution article. Host Name resolution might result in three separate lookups:

  1. Local Host file lookup
  2. Domain Name System lookup
  3. NetBIOS Name Server (WINS) lookup

NetBIOS Name Server lookup can impact the COP Discovery performance. IPCONFIG command displays whether "NetBIOS over Tcpip" is enabled and whether Name to IP resolution process will continue to WINS servers when there is no entry in Local Host or DNS.

NetBIOS overhead can be avoided by simply appending Domain Name to the Server name. For example specify TDPID.myCorp.com instead of TDPID.  So in summary I recommend Fully Qualified Domain Name (FQDN) on Windows platform as a general guideline.
 

Ignore ancestor settings: 
0
Apply supersede status to children: 
0

Convert .NET Data Provider for Teradata C# samples to VB or C++ - blog entry by NetFx

$
0
0

This blog describes how to convert .NET Data Provider for Teradata Learning Examples from C# to VB or C++.

.NET Data Provider for Teradata product installs Learning Examples in "<.NET Data Provider Installation Directory>\samples\LearningExamples" directory (e.g. "C:\Program Files\Teradata\NET Data Provider for Teradata\13.01.00\samples\LearningExamples"). These samples are written in C# language and we will ship VB samples some time in future.

But there is an easy way to convert the C# samples to VB as outlined below:

  1. Download and install ".NET Reflector" from http://www.red-gate.com/products/dotnet-development/reflector/.

  2. Compile one C# sample; see "<.NET Data Provider Installation Directory>\ samples\LearningExamples\Readme.doc" for details.

  3. Use ".NET Reflector" to open the resulting executable.

  4. Find the "Main(String[]): Void" method; right click and select Disassemble.

  5. Select "Visual Basic", "C#" or "MC++" from the toolbar.

 

For example I used the above procedure to convert:

static void Main(string[] args)
        {
            try
            {
                System.Console.WriteLine("Sample T20303TD: \n");
                System.Console.WriteLine(" Looking for .NET Data Provider for Teradata...");


                // Attempting to connect to Teradata
                System.Console.WriteLine(" Attempting to open a connection to Teradata via " +
                                         "the .NET Data Provider... \n");

                // Create a TdConnection object. A Connection 
                // represents a session with a specific database. Within the context 
                // of a Connection, SQL commands are executed and results are returned.
                // Creating and opening a database connection with the given connection string.                

                TdConnection con = new TdConnection(Constants.sConnection);
                con.Open();

                System.Console.WriteLine(" User " + Constants.sUser + " connected.");
                System.Console.WriteLine(" Connection to Teradata established. \n");

                try
                {
                    // Create a TdCommand object.  A command object executes 
                    // SQL commands on a specified Connection.  In order to specify which
                    // connection, set its connection property.  Command.ExecuteReader will return
                    // a TdDataReader which is used to read the result of a SQL command.
                    // Command.ExecuteNonQuery will perform the specified SQL command but
                    // will not return a reader.

                    TdCommand cmd = con.CreateCommand();
                    
                    try
                    {
                        // The following code will perform a SELECT query
                        // on the table.
                        cmd.CommandText = Constants.sSelect;

                        TdParameter par1 = cmd.CreateParameter();

                        par1.Value = Constants.sDept;
                        par1.ParameterName = "Dept";
                        par1.DbType = DbType.String;
                        par1.Size = Constants.sDept.Length;
                        cmd.Parameters.Add(par1);

                        // ExecuteReader method is being used without passing the SchemaOnly
                        // behavior because access to the ResultSet data is required
                        TdDataReader reader = cmd.ExecuteReader();

                        try
                        {
                            // Display result set table column meta data
                            displayRSMetaData(reader);

                            System.Console.WriteLine("\n\n Using ExecuteReader() to execute the following" +
                                                " SQL command: \n\n");
                            System.Console.WriteLine(Constants.sSelect + '\n');

                            // Extract and display result set table data
                            System.Console.WriteLine();
                            System.Console.WriteLine(" DISPLAYING RESULT SET DATA:");
                            System.Console.WriteLine(" ---------------------------");

                            int rowCount = 0;   // result set row counter

                            // If there are rows iterate through all returned values and display them                        
                            if (reader.HasRows)
                            {
                                // While there is more to read
                                while (reader.Read())
                                {
                                    rowCount++;   // increment retrieved row counter

                                    // Extract column values
                                    String name = reader.GetString(0);
                                    int id = reader.GetInt32(1);

                                    // Geting BLOB
                                    String bFilename = Environment.CurrentDirectory + @"\output\" + id + ".jpg";

                                    // Create a filestream to output BLOB to
                                    FileStream fs = new FileStream(bFilename, FileMode.Create, FileAccess.Write);

                                    try
                                    {
                                        // Create a buffer
                                        Byte[] bBuffer = new byte[100];
                                        
                                        // Call reader.GetTdBlob which will return a TdBlob.
                                        // TdBlobs support chunking so bytes can be read incrementally.
                                        TdBlob blob = reader.GetTdBlob(3);

                                        long numOfBytes;

                                        do
                                        {
                                            // Fill the buffer with bytes from the reader
                                            numOfBytes = blob.Read(bBuffer, 0, Constants.BUFFERSIZE);

                                            // Write bytes to the filestream
                                            fs.Write(bBuffer, 0, Constants.BUFFERSIZE);

                                        } while (numOfBytes == Constants.BUFFERSIZE);
                                        // The last segment of bytes will not fill the entire buffer
                                        // so we will continue while the number of bytes read fill the
                                        // entire buffer.
                                    }
                                    finally
                                    {
                                        fs.Close();
                                    }

                                    String cFilename = Environment.CurrentDirectory + @"\output\" + id + ".txt";

                                    // Create a filestream to output CLOB to
                                    StreamWriter sw = File.CreateText(cFilename);

                                    // Geting CLOB
                                    try
                                    {

                                        // Create a buffer
                                        Char[] cBuffer = new char[100];

                                        // Call reader.GetTdClob which will return a TdClob.
                                        // TdClobs support chunking so chars can be read incrementally.
                                        TdClob clob = reader.GetTdClob(2);

                                        long numOfChars;

                                        do
                                        {
                                            // Fill the buffer with chars from the reader
                                            numOfChars = clob.Read(cBuffer, 0, Constants.BUFFERSIZE);

                                            // Write bytes to the filestream
                                            sw.Write(cBuffer, 0, Constants.BUFFERSIZE);

                                        } while (numOfChars == Constants.BUFFERSIZE);
                                        // The last segment of chars will not fill the entire buffer
                                        // so we will continue while the number of chars read fill the
                                        // entire buffer.
                                    }
                                    finally
                                    {
                                        sw.Close();
                                    }

                                    // get the interval data
                                    TdIntervalYear service = TdIntervalYear.Parse(reader.GetString(4));
                                    TdIntervalDay workdays = TdIntervalDay.Parse(reader.GetString(5));

                                    System.Console.WriteLine("\n ROW " + rowCount);
                                    System.Console.WriteLine(" ----------");
                                    System.Console.WriteLine(" COLUMN empName : " + name);
                                    System.Console.WriteLine(" COLUMN empID : " + id);
                                    System.Console.WriteLine(" COLUMN empResume : Resume saved as " + cFilename);
                                    System.Console.WriteLine(" COLUMN empPhoto : Photo saved as " + bFilename);
                                    System.Console.WriteLine(" COLUMN empService : " + service.ToString());
                                    System.Console.WriteLine(" COLUMN empWorkDays : " + workdays.ToString());
                                }
                            }
                            System.Console.WriteLine("\n " + reader.RecordsReturned + " Row(s) retrieved. \n");
                        }
                        finally
                        {
                            reader.Close();
                        }
                    }
                    finally
                    {
                        cmd.Dispose();
                        System.Console.WriteLine(" Command Disposed. \n");
                    }
                }
                finally
                {
                    // Close the connection
                    System.Console.WriteLine(" Closing connection to Teradata...");
                    con.Close();
                    System.Console.WriteLine(" Connection to Teradata closed. \n");
                }

                System.Console.WriteLine(" Sample T20303TD finished. \n");
            }
            catch (DbException ex)
            {
                // A DbException was generated.  Catch it and display
                // the error information.
                // Note that there could be multiple error objects chained
                // together.                  
                if (ex is TdException)
                {
                    foreach (TdError err in ((TdException)ex).Errors)
                    {
                        System.Console.WriteLine(err.Message);
                    }
                }
                System.Console.WriteLine(ex.Message);
                System.Console.WriteLine("*** DbException caught ***");
            }
            catch (Exception ex)
            {
                // An exception of some other type has been generated.
                // Display the error information.
                System.Console.WriteLine(ex.Message);
                System.Console.WriteLine(ex.StackTrace);                
            }
        }

 

to

 

Private Shared Sub Main(ByVal args As String())
    Try 
        Console.WriteLine("Sample T20303TD: "& ChrW(10))
        Console.WriteLine(" Looking for .NET Data Provider for Teradata...")
        Console.WriteLine(" Attempting to open a connection to Teradata via the .NET Data Provider... "& ChrW(10))
        Dim con As New TdConnection(Constants.sConnection)
        con.Open
        Console.WriteLine((" User "& Constants.sUser & " connected."))
        Console.WriteLine(" Connection to Teradata established. "& ChrW(10))
        Try 
            Dim cmd As TdCommand = con.CreateCommand
            Try 
                cmd.CommandText = Constants.sSelect
                Dim par1 As TdParameter = cmd.CreateParameter
                par1.Value = Constants.sDept
                par1.ParameterName = "Dept"                par1.DbType = DbType.String
                par1.Size = Constants.sDept.Length
                cmd.Parameters.Add(par1)
                Dim reader As TdDataReader = cmd.ExecuteReader
                Try 
                    T20303TD.displayRSMetaData(reader)
                    Console.WriteLine(ChrW(10) & ChrW(10) & " Using ExecuteReader() to execute the following SQL command: "& ChrW(10) & ChrW(10))
                    Console.WriteLine((Constants.sSelect & ChrW(10)))
                    Console.WriteLine
                    Console.WriteLine(" DISPLAYING RESULT SET DATA:")
                    Console.WriteLine(" ---------------------------")
                    Dim rowCount As Integer = 0
                    If reader.HasRows Then
                        Do While reader.Read
                            rowCount += 1
                            Dim name As String = reader.GetString(0)
                            Dim id As Integer = reader.GetInt32(1)
                            Dim bFilename As String = String.Concat(New Object() { Environment.CurrentDirectory, "\output\", id, ".jpg" })
                            Dim fs As New FileStream(bFilename, FileMode.Create, FileAccess.Write)
                            Try 
                                Dim numOfBytes As Long
                                Dim bBuffer As Byte() = New Byte(100  - 1) {}
                                Dim blob As TdBlob = reader.GetTdBlob(3)
                                Do
                                    numOfBytes = blob.Read(bBuffer, 0, Constants.BUFFERSIZE)
                                    fs.Write(bBuffer, 0, Constants.BUFFERSIZE)
                                Loop While (numOfBytes = Constants.BUFFERSIZE)
                            Finally
                                fs.Close
                            End Try
                            Dim cFilename As String = String.Concat(New Object() { Environment.CurrentDirectory, "\output\", id, ".txt" })
                            Dim sw As StreamWriter = File.CreateText(cFilename)
                            Try 
                                Dim numOfChars As Long
                                Dim cBuffer As Char() = New Char(100  - 1) {}
                                Dim clob As TdClob = reader.GetTdClob(2)
                                Do
                                    numOfChars = clob.Read(cBuffer, 0, Constants.BUFFERSIZE)
                                    sw.Write(cBuffer, 0, Constants.BUFFERSIZE)
                                Loop While (numOfChars = Constants.BUFFERSIZE)
                            Finally
                                sw.Close
                            End Try
                            Dim service As TdIntervalYear = TdIntervalYear.Parse(reader.GetString(4))
                            Dim workdays As TdIntervalDay = TdIntervalDay.Parse(reader.GetString(5))
                            Console.WriteLine((ChrW(10) & " ROW "& rowCount))
                            Console.WriteLine(" ----------")
                            Console.WriteLine((" COLUMN empName : "& name))
                            Console.WriteLine((" COLUMN empID : "& id))
                            Console.WriteLine((" COLUMN empResume : Resume saved as "& cFilename))
                            Console.WriteLine((" COLUMN empPhoto : Photo saved as "& bFilename))
                            Console.WriteLine((" COLUMN empService : "& service.ToString))
                            Console.WriteLine((" COLUMN empWorkDays : "& workdays.ToString))
                        Loop
                    End If
                    Console.WriteLine((ChrW(10) & ""& reader.RecordsReturned & " Row(s) retrieved. "& ChrW(10)))
                Finally
                    reader.Close
                End Try
            Finally
                cmd.Dispose
                Console.WriteLine(" Command Disposed. "& ChrW(10))
            End Try
        Finally
            Console.WriteLine(" Closing connection to Teradata...")
            con.Close
            Console.WriteLine(" Connection to Teradata closed. "& ChrW(10))
        End Try
        Console.WriteLine(" Sample T20303TD finished. "& ChrW(10))
    Catch ex As DbException
        If TypeOf ex Is TdException Then
            Dim err As TdError
            For Each err In DirectCast(ex, TdException).Errors
                Console.WriteLine(err.Message)
            Next
        End If
        Console.WriteLine(ex.Message)
        Console.WriteLine("*** DbException caught ***")
    Catch ex As Exception
        Console.WriteLine(ex.Message)
        Console.WriteLine(ex.StackTrace)
    End Try
End Sub

 

 

 

There are alternative methods of converting C# to VB; for example: http://msdn.microsoft.com/en-us/magazine/cc163652.aspx

Ignore ancestor settings: 
0
Apply supersede status to children: 
0

Convert .NET Data Provider for Teradata C# samples to VB or C++ - comment by bilal.farooq

$
0
0

Is it possible to log in to the "MONITOR" partition of the Teradata DB using the .NET Driver? And then use the PMPC sub-system commands like: "MONITOR PHYSICAL RESOURCE"

I know it is possible with the JDBC Driver...


Convert .NET Data Provider for Teradata C# samples to VB or C++ - comment by NetFx

$
0
0

The .NET Data Provider for Teradata does not support MONITOR partition sessions.
I suggest requesting changes to the Open API (documented in Performance Management Manual) if Open API does not meet your needs.

How to specify a Transaction for a Batch Update with TdCommandBuilder and TdDataAdapter - blog entry by NetFx

$
0
0
Short teaser: 

TdCommandBuilder class, part  of  the .NET Data Provider for Teradata, generates Insert, Update and Delete commands for a Batch Update. But How can you associate a Transaction with CUD commands given that you have no direct control over the Command generation?

We need to start by looking at the basic relationship between TdCommandBuilder class and TdDataAdapter class. TdCommandBuilder has a DataAdapter property and it must be initialized. An Application must:

  1. Set the TdCommandBuilder.DataAdapter property.
  2. Set the TdDataAdaper.SelectCommand property of the associated TdDataAdapter object (TdCommandBuilder.DataAdapter).
  3. Set the TdCommand.Connection property of the associated TdCommand object (TdDataAdatper.SelectCommand).

The .NET Data Provider for Teradata will throw an exception when an application fails to initialize the required properties described above. For example the TdCommandBuilder.GetInsertCommand method will throw an "InvalidOperationException" when a) the TdCommandBuilder.DataAdapter property is not set or b) SelectCommand (DataAdatper.SelectCommand) of the associated TdDataAdapter is not set or c) Connection property  (DataAdatper.SelectCommand.Connection) of the associated SelectCommand is not set.

The TdCommandBuilder registers with the TdDataAdapter events. At runtime, during Batch Update, the TdDataAdapter will fire the events and the TdCommandBuilder object will have an opportunity to generate Insert, Update or Delete commands based on the TdDataAdapter.SelectCommand properties and the DataRow.

Now to specify an explicit Transaction we simply add a fourth rule. An application must:

  1. Set the TdCommand.Transaction property of the associated TdCommand object (TdDataAdatper.SelectCommand).

The example below illustrates how to setup the TdDataAdapter.SelectCommand property and use and explicit transaction:

private static void CreateCustomerAdapterTxWithCommandBuilder(Boolean rollback)
{
    using (TdConnection cn = new TdConnection("Data Source=TDPROD;User Id=X;Password=Y;"))
    {
        cn.Open(); 
         
        TdDataAdapter adapter = new TdDataAdapter();
        adapter.SelectCommand = cn.CreateCommand();
        adapter.SelectCommand.CommandText = "SELECT CustomerId, CompanyName from Customers";
         
        // Setup the DataTable schema.
        DataTable table = new DataTable();
        adapter.FillSchema(table, SchemaType.Source);
         
        // Create the transaction and associate with the DataAdapter.
        adapter.SelectCommand.Transaction = cn.BeginTransaction();
        
        // Associate CommandBuilder with the DataAdapter.
        TdCommandBuilder cmdBuilder = new TdCommandBuilder(adapter);
         
        // insert new rows into the DataTable.
        DataRow row = table.NewRow();
        row["CustomerId"] = 1;
        row["CompanyName"] = "Teradata Corp";
        table.Rows.Add(row);
         
        row = table.NewRow();
        row["CustomerId"] = 2;
        row["CompanyName"] = "XYZ Corp";
        table.Rows.Add(row);
         
        Int32 numberRows = adapter.Update(table);
         
        if (rollback)
        {
            adapter.SelectCommand.Transaction.Rollback();
        }
        else
        {
            adapter.SelectCommand.Transaction.Commit();
        }
    }
}
 
static void Main(string[] args)
{
    try
    {
        using (TdConnection cn = new TdConnection("Data Source=TDPROD;UserId=X;Password=Y;"))
        {
            cn.Open();
            TdCommand cmd = cn.CreateCommand();
            cmd.CommandText = "SELECT CAST(COUNT(*) as Decimal(38,0)) from Customers";
             
            Console.WriteLine("Number of Rows = {0}", cmd.ExecuteScalar());
             
            CreateCustomerAdapterTxWithCommandBuilder(true);
            Console.WriteLine("Number of Rows after DataAdapter Update followed by Rollback = {0}", 
                              cmd.ExecuteScalar());
             
            CreateCustomerAdapterTxWithCommandBuilder(false);
            Console.WriteLine("Number of Rows after DataAdapter Update followed by Commit = {0}", 
                              cmd.ExecuteScalar());
        }
    }
    catch (Exception e)
    {
        e.ToString();
    }
 
} 

  

Ignore ancestor settings: 
0
Apply supersede status to children: 
0

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - blog entry by NetFx

$
0
0
Short teaser: 
Step-by-Step instuctions to create a SQL Server Linked Server to the Teradata Database.

This blog outlines the steps to create a SQL Server 2008 (64-bit) R2  Linked Server to the Teradata Database.

1. Download and install

  1. The ODBC Driver for Teradata 64-bit
  2. The OLE DB Provider for ODBC 64-bit if it is not included in your OS. You can use the steps in the "Test the ODBC Data Source" section to see a list of OLE DB Providers currently installed on your server.

2. Create an ODBC Data Source

  1. Start the ODBC Data Source Administrator
  2. Select System DSN. User DSN will not work because SQL Server service will not have access to the User DSNs.
  3. Click Add ... button
  4. Select Teradata ODBC driver
  5. Fill in the required fields in the ODBC Driver Setup for Teradata Database dialog box

3. Test the ODBC Data Source

  1. Start Windows Explorer
  2. Navigate to a temporary directory
  3. Right-Click and select "New" - > "Text Document"
  4. Change the file extension to UDL (for example Foo.UDL)
  5. Double-Click the file to display the Data Link Properties dialog box
  6. Select the Provider tab
  7. Select the Microsoft OLE DB Provider for ODBC Drivers
  8. Select the Connection tab
  9. Select Use data source name radio button 
  10. Select the Data Source created in the previous section
  11. Specify a Teradata User ID
  12. Specify a Password
  13. Click the Test Connection button

 4. Create a SQL Server Linked Server Object

  1. Start SQL Server Management Studio
  2. Expand Server Objects
  3. Expand Linked Servers
  4. Expand Providers

  1. Make Sure MSDASQL (Microsoft OLE DB Provider for ODBC Drivers) is installed on the server
  2. Right Click on Linked Servers
  3. Select New Linked Server...
  4. Assign a name to the Linked Server; I suggest a single word name like TD.
  5. Select Microsoft OLE DB Provider for ODBC Drivers
  6. Set the Product Name to Teradata Database.
  7. Set the Data Source to the ODBC DSN Name created in section 2 above.

 

  1. Select Security page
  2. Select Be made using this security context
  3. Set the Remote login field to the Teradata Database User Id
  4. Set the With password field to the Teradata Database Password

 

  1. Click OK button

 5. Test the new Linked Server

  1. Open a New Query
  2. Execute a SELECT statement using a 4 part name (LinkedServerName..DatabaseName.TableName).
    1. The Linked Server Name crated in step 3 above. 
    2. The Teradata Database does not support Catalog; leave it blank.
    3. The Database Name
    4. The Table Name
Select * from TD..NorthwindEF.Customers

 References:

Ignore ancestor settings: 
0
Apply supersede status to children: 
0

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by jbmarshalliii

$
0
0

Great instructions. Thanks a bunch for this. Helped me out tremendously.

Setup SQL Server 2008 R2 Linked Server To the Teradata Database - comment by murphrp

$
0
0

@jbmarshalliii: Out of curiosity, how does this help you?

We would like to build a spreadsheet- or datasheet-like interface to capture data that is not already stored conveniently in an operational system. Generally, these data sources are on user desktops in Excel. We looked to Sharepoint (instead of Excel-only) to add some governance and sharing features, but we have not found the right solution to meet all our needs yet. Sharepoint can help us write directly to Teradata, but only with a form, not a datasheet interface. If you want the datasheet look and feel with Sharepoint, you have to write the data to SQL Server first, then move it separately to Teradata.

I'm wondering if setting up a linked server will help us use the datasheet view in Sharepoint and write directly to Teradata.

Viewing all 56 articles
Browse latest View live