sqlcmd scripting variables understanding problem - sql-server

try to run sqlcmd from powershell with some variables.
But get error.
Simple test. I know that this select is really simple but it is sufficient to show the problem.
this is the content of my sql file:
USE [master]
select name from sys.databases where NAME = $(db)
GO
now i run this:
sqlcmd -S testserver -v db="Test" -i \mssql_duplicate\testvariable.sql
i get following message:
Meldung "207", Ebene "16", Status "1", Server "testserver", Zeile 2
"Ungültiger Spaltenname "Test"."
So my question: Why the sqlcmd do this conversion?
When i put he name in the sql script it runs fine:
USE [master]
select name from sys.databases where NAME = "TEST"
GO
sqlcmd -S testserver -i \mssql_duplicate\testvariable.sql
Thanks for your help!

SQLCMD variables can substitute anything, in particular databases' and objects' names. In your example, however, it is used as an ordinary parameter, which is supposed to be of nvarchar(128) data type. So your code should look like this:
USE [master];
select name from sys.databases where NAME = N'$(db)';
GO
Without single quotes, SQL Server interprets your variable as an object name, hence the error.

Related

Is it possible to return query results as an Excel/CSV file formatted as a BLOB or base64 encoded string?

Limitations on some software I'm using require me to think outside the box, so can you have a query that automatically returns a "file" with the results in it? I imagine it would be as BLOB or a base 64 encoded string or something similar.
Using Microsoft SQL Server
You can use two methods to achieve this
1. Use SQLcmd
SQLCMD -S SERVERNAME -E -Q "SELECT Col1,Col2,Col3 FROM MyDatabase.dbo.MyTable"
-s "," -o "D:\MyData.csv"
Run this above command in a cmd and achieve the expected result.
2. Use OpenRawset
INSERT INTO OPENROWSET('Microsoft.ACE.OLEDB.12.0','Text;Database=D:\;HDR=YES;FMT=Delimited','SELECT * FROM [FileName.csv]')
SELECT Field1, Field2, Field3 FROM DatabaseName
You need to have the Microsoft.ACE.OLEDB.12.0 provider available. The Jet 4.0 provider will work, too, but it's ancient, so I used this one instead.
limitations:
The .CSV file will have to exist already. If you're using headers (HDR=YES), make sure the first line of the .CSV file is a delimited list of all the fields.
If you can create objects in the target database or another database on the same server, you could use the stored procedures and functions from my answer to this question: SSMS: Automatically save multiple result sets from same SQL script into separate tabs in Excel?
You would just need to exclude the #OutputFileName parameter to force output as a single column, single row varbinary(max).
select * into #systables from sys.tables;
select * into #syscolumns from sys.columns;
select * into #systypes from sys.types;
exec dbo.GetExcelSpreadsheetData
#Worksheets = 'sys.tables/#systables/autofilter|sys.columns/#syscolumns/autofilter|sys.types/#systypes'
drop table #systables;
drop table #syscolumns;
drop table #systypes;
Output (truncated):
ExcelSpreadsheetData
-------------------------------------
0x504B0304140000000800DB78295479400A1

Dynamic values to SQLCMD variable: Setvar

I am working with Visual Studio 2017 Database Project (Dacpac) and I have some SQLCMD variables in Publish file (in xml file) like below-
<SqlCmdVariable Include="ClientDBName">
<Value>Client_1</Value>
</SqlCmdVariable>
And my problem is, we have multiple clients and we are deploying the database changes by dacpac for multiple clients in once. So if I assign the static value for my SQLCMD variable "ClientDBName" like above example, it will take the same value (same db name "Client_1") for all the clients.
And to fix that I am using PreDeployment script. In which I am trying to assign dynamic value or db name to the SQLCMD variable "CleintDBName". Like below-
DECLARE #dbname varchar(50)
SET #dbName = "xyz"
:setvar ClientDBName #dbName
But this is not working. I explored it and found this would not work. Another way I am trying to do is by assign the dbname value via calling the script like below-
:setvar ClientDBName "C:\GetDatabaseName.sql"
But this is also not working.
So can anyone help me out on this, how we can assign dynamic values to SQLCMD variable?
The sqlpackage example command below specifies SQLCMD values with the /Variables: argument. These values are used instead of those in the publish profile.
SqlPackage.exe /Action:Publish /SourceFile:"YourDatabase.dacpac" /TargetDatabaseName:YourDatabaseName /TargetServerName:"." /Variables:"ClientDBName=YourValue"
If your actual need is the published database name, you could use the built-in DatabaseName SQLCMD variable instead of a user-defined SQLCMD variable, which will be the /TargetDatabaseName value.

SELECT query on a table with a space in the name using SQSH

I'm using SQSH (version 2.1) on Ubuntu 10.04 to connect to a MSSQL database using a command like this:
sqsh -S server -U user -P password -D database
I have a table called My Table, but I cannot find a way to run a SELECT query on it. This is what I've tried so far:
SELECT * FROM 'My Table'
go
Output: Incorrect syntax near 'My Table'. (I get the same for double quotes)
\set t="My Table"
SELECT * FROM $t
go
Output: Invalid object name 'My'. (Which is weird because if I do \echo $t, I get the full table name)
SELECT * FROM My\\ Table
go
Output: Invalid object name 'My'.
SELECT * FROM [My Table]
go
Output: Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier.
This last command works fine for table names without any spaces.
UPDATE: other commands work fine e.g. I can get the table description with:
SELECT column_name,data_type FROM information_schema.columns WHERE table_name = 'My Table'
go
Putting the table name in quotes doesn't work in MS SQL Server.
The correct way is using [ ]:
SELECT * FROM [My Table]
Im using SQL 2008R2, and the following works for me
['table name']
Finally found the solution. I had to add the following 2 lines to /etc/freetds/freetds.conf
tds version = 8.0
client charset = UTF-8
Try setting QUOTED_IDENTIFIER to ON when using SQL Server. For more info about QUOTED_IDENTIFIER see: http://msdn.microsoft.com/en-us/library/ms174393.aspx

Mysql dump of single table

I am trying to make some normal (understand restorable) backup of mysql backup. My problem is, that I only need to back up a single table, which was last created, or edited. Is it possible to set mysqldump to do that? Mysql can find the last inserted table, but how can I include it in mysql dump command? I need to do that without locking the table, and the DB has partitioning enabled.... Thanks for help...
You can use this SQL to get the last inserted / updated table :-
select table_schema, table_name
from information_schema.tables
where table_schema not in ("mysql", "information_schema", "performance_schema")
order by greatest(create_time, update_time) desc limit 1;
Once you have the results from this query, you can cooperate it into any other language (for example bash) to produce the exact table dump).
./mysqldump -uroot -proot mysql user > mysql_user.sql
For dumping a single table use the below command.
Open cmd prompt and type the path of mysql like c:\program files\mysql\bin.
Now type the command:
mysqldump -u username -p password databasename table name > C:\backup\filename.sql
Here username - your mysql username
password - your mysql password
databasename - your database name
table name - your table name
C:\backup\filename.sql - path where the file should save and the filename.
If you want to add the backup table to any other database you can do it by following steps:
login to mysql
type the below command
mysql -u username -p password database name < C:\backup\filename.sql

How do I retrieve and image datatype from SQLServer 2005 without programmatic access from some other language

I have a SQL Server 2005 table with an image datatype as on of the table fields. I have a specific row I am interested. I'd like to write the binary data in the image field to a file on a network share.
Let's call the share \server\sharename
This worked for me. Obviously path names and instance names may need to be altered your end.
It requires master..xp_cmdshell enabled (but you could just run bcp directly if there is no need to do it in T-SQL)
EXEC master..xp_cmdshell
'bcp "SELECT [LargePhoto] FROM [AdventureWorks2008].[Production].[ProductPhoto] WHERE [ProductPhotoID]=70" queryout C:\temp\YourImage.jpg -S(local)\SQL2008 -T -fC:\temp\test.fmt'
It requires the following format file C:\temp\test.fmt
9.0
1
1 SQLBINARY 0 0 "" 1 col1 ""

Resources