I want to use tclodbc from Linux environment to connect to a MS SQL server. I have the driver (freeTDS) and the connection string. But I don't know how to configure the driver to be used by tclodbs. There is a command
database configure operation driver attributes
But I don't know what to put as operation and attributes, and whether this is the right command.
Related to my question: Accessing Microsoft SQL Server from Tcl running on GNU/Linux
OK, here's my take based on these guides about how to make a DSN-less connection using the FreeTDS driver.
I've tested it a Debian Lenny system having tclodbc 2.5-5, unixodbc 2.2.11 and libdbd-freetds 0.8.2-1-4.1 and tcl 8.4.16-2 installed against an instance of Microsoft SQL Server 2005.
package require tclodbc
proc cs_append {varName args} {
set alen [llength $args]
if {$alen < 2 || $alen % 2 != 0} {
return -code error "Wrong # args: should be varName key value ?key value?"
}
upvar 1 $varName qs
foreach {key value} $args {
if {$qs ne ""} {
append qs \;
}
append qs $key = \{ [string map {\{ \\\{} $value] \}
}
}
set user test
set pass secret
set cs ""
cs_append cs DRIVER FreeTDS UID $user PWD $pass \
Server myserver.domain.local \
ClientCharset UTF-8 \
APP "My test app"
database connect db $cs
foreach row [db {select * from MyDatabase..MyTable}] {
puts $row
}
db disconnect
Some notes:
The FreeTDS driver must be known to the ODBC subsystem by means of it being registeded in the /etc/odbcinst.ini file. I suppose that at least on my system appropriate packages take care of this by themselves but you'd better verify if you have FreeTDS registered in that file, otherwise that DRIVER=FreeTDS bit in the connection string won't work as ODBC will have no idea how to load the named driver library.
The ClientCharset and APP connection string parameters do not work in my case. While I can live with the second, the first one sucks big time because in this case the character data is returned in some botched encoding.
But there's no such problem when I use named server from the /etc/freetds/freetds.conf file using the ServerName=THAT_SERVER instead of Server=SERVER_HOST in the connection string. Unfortunately, this kind of defeats half of the purpose of using DSN-less setup.
Quite possibly it's a bug in my version of the FreeTDS driver, and I have a really outdated system here, so YMMV and you better check yourself on your system.
If we look at the documentation, we see that there are 6 operations, of which the one you probably want is add_dsn. An example is included (below, with a small correction):
set driver "Microsoft Access Driver (*.mdb)"
set attributes [list "DSN=mydsn" "DBQ=c:\mydb.mdb" "FIL=MS Access"]
database configure add_dsn $driver $attributes
I'm afraid you'll have to consult the FreeTDS documentation to get the right collection of attributes, but I think (based on this evidence) that you'll have the driver being FreeTDS and the attributes might be OK if it is an empty list (or with just TDS_Version=5.0 in it). I really don't know too much about configuring ODBC…
Related
I have been researching on this for a couple of days but have been going in circles here.
I need to write a script that fetches the data from Oracle db and do something with the data. In my script I will have to fetch data multiple times.
My machine has the SQLDeveloper-21.4.3 which I got from installing InstantClient-Basic-Windows-21.3.0. I use the SQL Developer to connect to the db which is on another machine; this is how I can look into tables, views etc. of the db.
Secondly, this script will be hosted on another server that runs Windows-Server-2012-R2. I am just using my machine to write the script because I cannot use the server to do this. Therefore, I am looking for a solution that requires minimum amount of installing.
Thirdly, we do not have Oracle commercial license. This Oracle db I am trying to access is on the machine installed by a third party that installed some instruments. This company uses Oracle as they collect data on the instruments installed.
I was hoping the solution would be something similar to invoking connection to MS SQL where I downloaded module that gave cmdlets to connect to the MS SQL.
Oracle does have Oracle Modules for PowerShell but neither have I found information on how to use them nor have I understood the little information provided by Oracle on this. For this to work one of the requirement is:
A configuration file and key pair used for signing API requests, with
the public key uploaded to Oracle Cloud using Oracle Cloud
Infrastructure Console. Only the user calling the API should possess
the private key.
I don't know the heck Oracle is talking about here. Like, what is this configuration file, where is it? Where would I get the key pair from for signing API request. What is Oracle Infrastructure Console, where do I get it from? You get the idea.
Link: https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/powershell.htm
Therefore, I went the .DLL route.
This is what I have done so far:
I installed Oracle.ManagedDataAccess.Core -Version 3.21.61 from NuGet.
Unzipped the package and moved the Oracle.ManagedDataAccess.dll to the location of my script.
The code is:
$OracleDLLPath = "C:\Users\Desktop\CNC_File_Transfer_VSCode\Fastems_NicNet\Oracle.ManagedDataAccess.dll"
$datasource = " (DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 10.50.61.9)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = Fa1)
(FAILOVER_MODE = (TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5))))"
$username = "username"
$password = "password"
$queryStatment = "SELECT [PROG_TYPE] FROM NC_PROGRAMS FETCH FIRST 10 ROWS ONLY"
#Load Required Types and modules
Add-Type -Path $OracleDLLPath
Import-Module SqlServer
Write-Host $queryStatment
#Create the connection string
$connectionstring = 'User Id=' + $username + ';Password=' + $password + ';Data Source=' + $datasource
#Creates a data adapter for the command
$da = New-Object Oracle.ManagedDataAccess.Client.OracleDataAdapter($cmd);
#The Data adapter will fill this DataTable
$resultSet = New-Object System.Data.DataTable
#Only here the query is sent and executed in Oracle
[void]$da.fill($resultSet)
#Close the connection
$con.Close()
WRITE-HOST $resultSet
This gives an error though:
Add-Type : Unable to load one or more of the requested types. Retrieve
the LoaderExceptions property for more information.
I am new to programming in general. I would really appreciate if someone could provide detailed steps on resolving this. Thanks in advance.
I use Microsoft SQL Server Management Studio on Windows 10 to connect to the following database and this is what the login screen looks like:
Server Type: Database Engine
Server Name: sqlmiprod.b298745190e.database.windows.net
Authentication: SQL Server Authentication
Login: my_user_id
Password: my_password
This recent R Studio article offers an easy way to connect to SQL Servers from R Studio using the following:
con <- DBI::dbConnect(odbc::odbc(),
Driver = "[your driver's name]",
Server = "[your server's path]",
Database = "[your database's name]",
UID = rstudioapi::askForPassword("Database user"),
PWD = rstudioapi::askForPassword("Database password"),
Port = 1433)
I have two questions
What should I use as "[your driver's name]"?
What should I use as "[your database's name]"?
The server path I'll use is sqlmiprod.b298745190e.database.windows.net (from above) and I'll leave the port at 1433. If that's wrong please let me know.
Driver
From #Zaynul's comment and my own experience, the driver field is a text string with the name of the ODBC driver. This answer contains more details on this.
You probably want someting like:
Driver = 'ODBC Driver 17 for SQL Server' (from #Zaynul's comment)
Driver = 'ODBC Driver 11 for SQL Server' (from my own context)
Database
The default database you want to connect to. Roughly equivalent to starting an SQL script with
USE my_database
GO
If all your work will be within a single database then puts its name here.
In some contexts you should be able to leave this blank, but you then have to use the in_schema command to add the database name every time you connect to a table.
If you are working across multiple databases, I recommend putting the name of one database in, and then using the in_schema command to specify the database at every point of connection.
Example using the in_schema command (more details):
df = tbl(con, from = in_schema('database.schema', 'table'))
Though I have not tried it, if you do not have a schema then
df = tbl(con, from = in_schema('database', 'table'))
Should also work (I've been using this hack without issue for a while).
When trying to run the following in Redis using booksleeve.
using (var conn = new RedisConnection(server, port, -1, password))
{
var result = conn.Server.FlushDb(0);
result.Wait();
}
I get an error saying:
This command is not available unless the connection is created with
admin-commands enabled"
I am not sure how do i execute commands as admin? Do I need to create an a/c in db with admin access and login with that?
Updated answer for StackExchange.Redis:
var conn = ConnectionMultiplexer.Connect("localhost,allowAdmin=true");
Note also that the object created here should be created once per application and shared as a global singleton, per Marc:
Because the ConnectionMultiplexer does a lot, it is designed to be
shared and reused between callers. You should not create a
ConnectionMultiplexer per operation. It is fully thread-safe and ready
for this usage.
Basically, the dangerous commands that you don't need in routine operations, but which can cause lots of problems if used inappropriately (i.e. the equivalent of drop database in tsql, since your example is FlushDb) are protected by a "yes, I meant to do that..." flag:
using (var conn = new RedisConnection(server, port, -1, password,
allowAdmin: true)) <==== here
I will improve the error message to make this very clear and explicit.
You can also set this in C# when you're creating your multiplexer - set AllowAdmin = true
private ConnectionMultiplexer GetConnectionMultiplexer()
{
var options = ConfigurationOptions.Parse("localhost:6379");
options.ConnectRetry = 5;
options.AllowAdmin = true;
return ConnectionMultiplexer.Connect(options);
}
For those who like me faced the error:
StackExchange.Redis.RedisCommandException: This operation is not
available unless admin mode is enabled: ROLE
after upgrading StackExchange.Redis to version 2.2.4 with Sentinel connection: it's a known bug, the workaround was either to downgrade the client back or to add allowAdmin=true to the connection string and wait for the fix.
Starting from 2.2.50 public release the issue is fixed.
I would like to know if it is possible to know if a instance of sql server is in mirror/prinicipal by running any sql query? and secondly i want to run this on say 60-80 instances everyday at 4am automatically possible? I would like to use powershell used it before quite easy to use from experience. Tks
It is possible. You will need to play around with SMO objects.
$server = "dwhtest-new"
$srv = New-Object Microsoft.SqlServer.Management.Smo.Server $server
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$dbs = $srv.Databases
foreach ($db1 in $dbs)
{
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $db1
$DatabaseName = $db.Name
Write-Host $DatabaseName
Write-Host "MirroringStatus:" $db.MirroringStatus
Write-Host "DBState:" $db.Status
Write-Host
}
If your DB's mirroring is still intact you will recieve 'Synchronized' for MirroringStatus and its its the Primary it will say "Normal" for the status and if its the failover it will say "Restoring". Unfortunately there is no way, that im aware of, to just pull out the status of "Mirror" or "principle". You will jsut have to build logic to check both fo those values.
Restoring
It depends on how are you going to setup the job?
If you want to run it from one central server that collects all the information then SMO would be the way to go with PowerShell. The answer provided by KickerCost can work but would need some more work to be able to run it for multiple servers. It would be best to take his example and turn it into a working function that will allow the server names to be piped in.
If you are going to just run a job locally on each server (scheduled task or SQL Agent job) that may point to the script on a network share, then maybe output that info to a file (like servername_instance.log) you can use a one-liner with SQLPS:
dir SQLSERVER:\SQL\KRINGER\Default\Databases | Select Name, MirroringStatus
KRINGER is my server name, with a default instance. If you have named instances then replace the "default" with the instance name.
Your output from this command would be similar to this:
Name MirroringStatus
---- ---------------
AdventureWorks None
AdventureWorksDW None
Obviously I don't have any databases involved in mirroring.
I have mod_perl2 running on a virtual host and I'm trying to make my mysql connection persistent between requests to handle server load. I have read all of the documentation and a book on the topic and I still have no idea why this bare-bones implementation of a mod_perl2 web application replies with "It's broken!".
package Test;
use strict;
use warnings;
use Apache2::Const;
use Carp qw{croak};
use DBI;
our $mysql_handle;
sub handler {
print "Content-Type: text/plain\n\n";
print (defined $mysql_handle ? "It's defined!" : "It's broken!");
return Apache2::Const::OK;
}
sub child_init {
my ($db, $host, $port, $user, $pass)
= qw{app_db localhost 3306 app_user app_pass};
$mysql_handle
= DBI->connect("dbi:mysql:database=$db;host=$host;port=$port", $user, $pass)
or croak("Failed to establish a connection with mysqld: $DBI::errstr");
return Apache2::Const::OK;
}
1;
This is very strange and makes no sense at all to me. It's as if $mysql_handle is lexically-scoped -- when it's not! Please, can some one explain this to me?
You should look at Apache::DBI for mysql connection persistance in mod_perl. It overloads DBI's connect and disconnect which allows you to use DBI->connect(...) normally, with the added benefit of the code working in or out of a mod perl environment.
As far as the scoping issue, I'd need a little more feedback on your mp setup. I would try use vars '$mysql_handle' or even $Test::mysql_handle = DBI->connect(...) and see if you don't get the results you are looking for.