Docker with SQL Server cannot insert values into database with sqlcmd - sql-server

I have a docker file where I import two databases.
FROM mcr.microsoft.com/mssql/server
RUN mkdir -p /var/opt/mssql/backup
COPY clean_SCManager.bak /var/opt/mssql/backup/SCManager.bak
COPY clean_SCServer.bak /var/opt/mssql/backup/SCServer.bak
COPY SCManager-setup.sql /var/opt/mssql/SCManager-setup.sql
COPY startup.sh /var/opt/mssql/startup.sh
ENV MSSQL_SA_PASSWORD=P#ssw0rd
ENV ACCEPT_EULA=Y
RUN chmod +x /var/opt/mssql/startup.sh
CMD /var/opt/mssql/startup.sh
EXPOSE 1433
Now I want to insert some values into one of my databases, for that I am using a SQL file which contains a INSERT INTO command.
USE SCManager;
GO
INSERT INTO epls_dbo.Account("uid", "login", "password_hash", "lastLogin", "failedLogins", "locked", "role", "locale", "accountPenIdUid")
VALUES (4294967306, 'sysadm', '2398ef2774cd07f31037e9347de3e660', '2017-09-12 14:50:35.607', 0, 'False', 'Admin', 'en_US', NULL);
This SQL will be called by a bash script, in this I am using sqlcmd to execute the SQL script.
#/bin/bash
echo "startup.sh is called, starting sqlserver"
/opt/mssql/bin/sqlservr &
echo "start sleeping for 20 seconds"
sleep 20
echo "sleeping done"
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "P#ssw0rd" -Q "RESTORE FILELISTONLY FROM DISK = '/var/opt/mssql/backup/SCServer.bak'"
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "P#ssw0rd" -Q "RESTORE FILELISTONLY FROM DISK = '/var/opt/mssql/backup/SCManager.bak'"
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "P#ssw0rd" -Q "RESTORE DATABASE SCManager FROM DISK = '/var/opt/mssql/backup/SCManager.bak' WITH MOVE 'SCManager' TO '/var/opt/mssql/data/SCManager.mdf', MOVE 'SCManager_log' TO '/var/opt/mssql/data/SCManager_log.ldf'"
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "P#ssw0rd" -Q "RESTORE DATABASE SCServer FROM DISK = '/var/opt/mssql/backup/SCServer.bak' WITH MOVE 'SCServer' TO '/var/opt/mssql/data/SCServer.mdf', MOVE 'SCServer_log' TO '/var/opt/mssql/data/SCServer_log.ldf'"
sleep 10
/opt/mssql-tools/bin/sqlcmd -S localhost -U SA -d SCManager -P "P#ssw0rd" -i "/var/opt/mssql/SCManager-setup.sql"
tail -f /dev/null
When I run the docker image I can see in the logs that the database has been imported and that the sql file has been executed but the sql has not been successfully executed
Changed database context to 'SCManager'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'uid'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'login'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'password_hash'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'lastLogin'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'failedLogins'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'locked'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'role'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'locale'.
Msg 207, Level 16, State 1, Server fb5db2041be5, Line 4
Invalid column name 'accountPenIdUid'.
When I connect to the running docker container I can query the database, so the database is available and the table which I want to insert into exits
root#fb5db2041be5:/# /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "P#ssw0rd" -d SCManager -Q "select * from epls_dbo.Account"
uid login password_hash lastLogin failedLogins locked role
locale accountPenIdUid
-------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------- ----------------------- ------------ ------ ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------ --------------------
(0 rows affected)
Also I can execute in the bash my insert into command an it inserts correctly the values, why does it not work by calling it from my bash script?

Related

How to restore database when files are claimed?

I have to restore a database and am following this official documentation where I follow two steps:
- List the files
- Run the Restore command with respect to the files aforementioned.
However, I am facing "already claimed" error.
I tried to use different names but it is not possible since the backup has certain files. I also tried other answers across different domains, all have GUI.
The first command that I ran was:
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd -S localhost \
-U SA -P '<YourStrong#Passw0rd>' \
-Q 'RESTORE FILELISTONLY FROM DISK = "/var/opt/mssql/backup/us_national_statistics.bak"' \
| tr -s ' ' | cut -d ' ' -f 1-2
I got the following output:
LogicalName PhysicalName
-------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
us_national_statistics C:\Program
us_national_statistics_log C:\Program
Then, as per the documentation, I ran this command:
sudo docker exec -it sql1 /opt/mssql-tools/bin/sqlcmd \
-S localhost -U SA -P '<YourStrong#Passw0rd>' \
-Q 'RESTORE DATABASE US_NATIONAL FROM DISK = "/var/opt/mssql/backup/us_national_statistics.bak" WITH MOVE "us_national_statistics" TO "C:\Program", MOVE "us_national_statistics_log" TO "C:\Program"'
Here, I get the following error:
Msg 3176, Level 16, State 1, Server 0a6a6aac7476, Line 1
File 'C:\Program\New' is claimed by 'us_national_statistics_log'(2) and 'us_national_statistics'(1). The WITH MOVE clause can be used to relocate one or more files.
Msg 3013, Level 16, State 1, Server 0a6a6aac7476, Line 1
RESTORE DATABASE is terminating abnormally.
I expect the database to be restored.
You can't restore to C:\Program for multiple reasons. That's not a full path (you seem to have lost the string after the first space in Program Files); the data and log can't both be put in the same file; you don't typically have write access to the root of any drive; and C:\ is not valid in Docker or Linux.
You need the LogicalName, but you should not be using the PhysicalName directly, either in the case where you are restoring to Docker or Linux, or in the case where you are restoring a database alongside an existing copy that you want to keep, or in the case where you are restoring a database to a different instance (which will more than likely have a different data folder structure).
Try:
RESTORE DATABASE US_NATIONAL_COPY
FROM DISK = "/var/opt/mssql/backup/us_national_statistics.bak"
WITH REPLACE, RECOVERY,
MOVE "us_national_statistics" TO "/var/opt/mssql/data/usns_copy.mdf",
MOVE "us_national_statistics_log" TO "/var/opt/mssql/data/usns_copy.ldf";

ms sql server linux docker asking for file in D:\

I am now trying to restore .bak file of MS SQL Server 2008 to docker mssql-serverlinux in order to see the content inside and draw my own scheman in Postgres
I read this and conclude that my command to restore it to my container supposed to be in single line
sqlcmd -S localhost -U SA -Q "RESTORE DATABASE mytrash FROM DISK = '/trash/dbWINS_MPMBA201803141100.bak' WITH FILE = 1, NOUNLOAD, REPLACE, NORECOVERY, STATS = 5"
Here is the full error and directory I place the bak file. Since it will be no use when I finish I name the directory trash in order to delete it later.
root#891ce27ef07a:/trash# /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -Q "RESTORE DATABASE mytrash FROM DISK = '/trash/dbWINS_MPMBA201803141100.bak' WITH FILE = 1, NOUNLOAD, REPLACE, NORECOVERY, STATS = 5"
Password:
Msg 5133, Level 16, State 1, Server 891ce27ef07a, Line 1
Directory lookup for the file "D:\MSSQL\Data\dbWINS_MPMBA.mdf" failed with the operating system error 2(The system cannot find the file specified.).
Msg 3156, Level 16, State 3, Server 891ce27ef07a, Line 1
File 'dbERP_New_Data' cannot be restored to 'D:\MSSQL\Data\dbWINS_MPMBA.mdf'. Use WITH MOVE to identify a valid location for the file.
Msg 5133, Level 16, State 1, Server 891ce27ef07a, Line 1
Directory lookup for the file "D:\MSSQL\Data\dbWINS_MPMBA_1.ldf" failed with the operating system error 2(The system cannot find the file specified.).
Msg 3156, Level 16, State 3, Server 891ce27ef07a, Line 1
File 'dbERP_New_Log' cannot be restored to 'D:\MSSQL\Data\dbWINS_MPMBA_1.ldf'. Use WITH MOVE to identify a valid location for the file.
Msg 3119, Level 16, State 1, Server 891ce27ef07a, Line 1
Problems were identified while planning for the RESTORE statement. Previous messages provide details.
Msg 3013, Level 16, State 1, Server 891ce27ef07a, Line 1
RESTORE DATABASE is terminating abnormally.
root#891ce27ef07a:/trash# pwd
/trash
root#891ce27ef07a:/trash# ls
dbWINS_MPMBA201803141100.bak
root#891ce27ef07a:/trash#
My docker-compose. For any one who would like to show me the answer.
version: "3.5"
services:
mssql:
image: "microsoft/mssql-server-linux"
environment:
SA_PASSWORD: "hardlongpassword"
ACCEPT_EULA: "Y"
volumes:
- type: bind
source: ./data
target: /trash
Update
I tried to move the location according to the TZHX comment from this
I got new error now
1>
1> RESTORE DATABASE NewDB
2> FROM DISK = '/trash/dbWINS_MPMBA201803141100.bak'
3> WITH MOVE 'NewDB' TO '/trash/NewDB.mdf',
4> MOVE 'NewDB' TO '/trash/NewDB_Log.ldf'
5> GO
Msg 3234, Level 16, State 2, Server 891ce27ef07a, Line 1
Logical file 'NewDB' is not part of database 'NewDB'. Use RESTORE FILELISTONLY to list the logical file names.
Msg 3013, Level 16, State 1, Server 891ce27ef07a, Line 1
RESTORE DATABASE is terminating abnormally.
Update2:
From this. I am reading the output
1> RESTORE FILELISTONLY FROM DISK ='/trash/dbWINS_MPMBA201803141100.bak' WITH FILE=1
2> GO
LogicalName PhysicalName Type FileGroupName Size MaxSize FileId CreateLSN DropLSN UniqueId ReadOnlyLSN ReadWriteLSN BackupSizeInBytes SourceBlockSize FileGroupId LogGroupGUID DifferentialBaseLSN DifferentialBaseGUID IsReadOnly IsPresent TDEThumbprint SnapshotUrl
-------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- -------------------------------------------------------------------------------------------------------------------------------- -------------------- -------------------- -------------------- --------------------------- --------------------------- ------------------------------------ --------------------------- --------------------------- -------------------- --------------- ----------- ------------------------------------ --------------------------- ------------------------------------ ---------- --------- ------------------------------------------ ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
dbERP_New_Data D:\MSSQL\Data\dbWINS_MPMBA.mdf D PRIMARY 256311296 35184372080640 1 0 0 00000000-0000-0000-0000-000000000000 0 0 143196160 512 1 NULL 73150000001788800289 B582C71F-CCDF-4030-9CF8-30785258D515 0 1 NULL NULL
dbERP_New_Log D:\MSSQL\Data\dbWINS_MPMBA_1.ldf L NULL 2945384448 35184372080640 2 0 0 00000000-0000-0000-0000-000000000000 0 0 0 512 0 NULL 0 00000000-0000-0000-0000-000000000000 0 1 NULL NULL
(2 rows affected)
update3:
1> RESTORE DATABASE dbERP_New_Data
2> FROM DISK = '/trash/dbWINS_MPMBA201803141100.bak'
3> WITH MOVE 'dbERP_New_Data' TO '/trash/dbERP_New_Data.mdf',
4> MOVE 'dbERP_New_Log' TO '/trash/dbERP_New_Log.ldf'
5> GO
Msg 5120, Level 16, State 101, Server 891ce27ef07a, Line 1
Unable to open the physical file "/trash/dbERP_New_Data.mdf". Operating system error 87: "87(The parameter is incorrect.)".
Msg 3013, Level 16, State 1, Server 891ce27ef07a, Line 1
RESTORE DATABASE is terminating abnormally.
Update4:
Apparently, restoring database files to a volume on the host doesn't work (at least not with the default options on a MacOS host; there may be advanced Docker options to get it to work). What will work is restoring the files within the host itself:
RESTORE DATABASE dbERP_New_Data
FROM DISK = '/trash/dbWINS_MPMBA201803141100.bak'
WITH MOVE 'dbERP_New_Data' TO '/root/dbERP_New_Data.mdf',
MOVE 'dbERP_New_Log' TO '/root/dbERP_New_Log.ldf'
Probably not something you should do for a production setup, but good enough if you only need to access the database for a short while.

sqlcmd utility returns "Could not find stored procedure"

I am trying to execute a stored procedure using this command line utility:
sqlcmd -m 1 -S inxcert -U user1 -P u8er1 -i "D:\ESP\RunSQL.sql" -h -1 -o "D:\ESP\testoutput.txt"
Following is what I have written in RunSQL.sql:
exec spc.load_tables
Though the stored procedure exist in the database, credentials are correct and SQL Server runs fine when run from SSMS I am getting the following error in the output file:
Msg 2812, Level 16, State 62, Server I0160SQL03\I0160SQL03, Line 1
Could not find stored procedure 'spc.mjr_vs_load_tables'.
Please help me to learn how to resolve the error.
Looks like it's executing against the default database (probably master) so not finding your procedure.
Try either adding:
USE [DBNAME]
to RunSQL.sql, or specifying:
-d DBNAME
to your sqlcmd parameters.

BCP export queryout error

In Sql Server 2000, connected using osql command line, connected through a DSN ODBC, Using the OLEDB Provider, I am trying to export the result of a Stored Procedure to an XML file. However I get and error no matter how far down I simplify the query.
if I use the OUT qualifer I get the following error:
Msg 179, Level 15, State 1, Server SERVER, Line 1
Cannot use the OUTPUT option when passing a constant to a stored procedure.
which from my reading is expected. but no matter how I use QUERYOUT I get following error:
Msg 170, Level 15, State 1, Server SERVER, Line 1
Line 1: Incorrect syntax near 'queryout'.
Here is the simplest query I can muster and I still get this error:
bcp "Select * FROM [SERVER].[SCHEMA].[TABLE]" queryout \\fileserver\test.txt -c -T
You need to create a text file such as
set nocount on
select * from table
and save it. Let say it is in c:(input_text).txt
Then, in SQL server management studio, create and run following osql query to get output_text.
osql -U (login id) -P (password) -S (server name) -d (db name) -i c:(input_text).txt -o c:(output_text).txt -h-1 -s " " -n -w 2000

Return value of SQLCMD

I need to check the exit status (success/failure) of a query run through SQLCMD utility. For example, the server I am connecting doesn't have a database name EastWind. Then, the command below fails with the message ...
> "C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE"
-S ZEPHIR -E -Q "USE WestWind"
Changed database context to 'WestWind'.
> echo %errorlevel%
0
> "C:\Program Files\Microsoft SQL Server\100\Tools\Binn\SQLCMD.EXE"
-S ZEPHIR -E -Q "USE EastWind"
Database 'EastWind' does not exist. Make sure that the name is entered correctly
> echo %errorlevel%
0
I see that the return value is the same in both the cases. How can I check if a command has failed in SQLCMD?
You need to use the -V option
Note: That's a capital -V, not a lowercase -v.
Example:
> SQLCMD.EXE -S whatever -E -V16 -Q "USE does_not_exist"
Msg 911, Level 16, State 1, ...
Could not locate entry ...
> echo %ERRORLEVEL%
16
Update: Alternatively, you can use the -b option, which has different semantics to the execution (the whole batch stops on the first error). YMMV.
Example:
> SQLCMD.EXE -S whatever -E -b -Q "USE does_not_exist"
Msg 911, Level 16, State 1, ...
Could not locate entry ...
> echo %ERRORLEVEL%
1
You can also combine -b and -V.
I am not sure, but did you tried SQLCMD -m switch? sqlcmd Utility
-m error_level - Controls which error messages are sent to stdout. Messages that have a severity level greater than or equal to this level are sent. When this value is set to -1, all messages including informational messages, are sent. Spaces are not allowed between the -m and -1. For example, -m-1 is valid, and -m -1 is not.

Resources