I have a requirement where i need to see data for every week using a sql query.
I used query like SELECT * from table Between '27-08-2012' and '30-08-2012'.
Now my requirement is that i need a batch file that can given me this script based on user selection. Like user can give start date and end date and sql query should generate automatically.
A much less error prone way to get a date range is to use a graphical date picker
than manual user input which has to be checked for validity.
(month/day names will match your locale, not my German one)
This PowerShell script:
# Function Pick-Date
[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
Function Pick-Date {
$Cal = new-object System.Windows.Forms.MonthCalendar
$Cal.ShowWeekNumbers = $true
$Cal.MaxSelectionCount = 10 # change this value for the max date distance
$Cal.Dock = 'Fill'
$Form = new-object Windows.Forms.Form
$Form.text = "Drag the mouse to select a date range then hit [enter]"
$Form.Size = new-object Drawing.Size #(656,620)
$btnSelect = new-object System.Windows.Forms.Button
$btnSelect.Size = "1,1"
$btnSelect.add_Click({ $Form.close() })
$Form.Controls.Add($btnSelect )
$Form.AcceptButton = $btnSelect
$Form.Controls.Add($Cal)
$Form.Add_Shown({$Form.Activate()})
[void]$Form.showdialog()
return ("SELECT * from table Between '"+
(Get-Date($Cal.SelectionStart) -format 'dd-MM-yyyy')+
"' and '"+
(Get-Date($Cal.SelectionEnd) -format 'dd-MM-yyyy')+
"'")
}
Pick-Date
Will have this output, you can save to a file.sql
PS> .\Pick-Date.ps1
SELECT * from table Between '27-08-2012' and '31-08-2012'
EDIT
This batch wrapper for the powerShell script will store the query in the variable SqlQuery
#Echo off&SetLocal EnableExtensions EnableDelayedExpansion
::Wrap Pick-Date.ps1 in same folder as batch
For /F "delims=" %%%A in (
'Powershell -NoP -NonI -NoLogo -File Pick-Date.ps1 '
) Do Set "SqlQuery=%%A"
Set SqlQuery
Related
I have this code that I got from a website and it's connected to my SQL Server using window authentication but I'm not sure how can I choose a database and query some table?.
[Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-Null
$s = new-object ('Microsoft.SqlServer.Management.Smo.Server') "server instance"
$s.ConnectionContext.LoginSecure=$true
$s.Databases | select name, size, status
If I run this code, it show me a list of databases but I want to choose a database called "LitHold" and query some table from that database inside.
For SMO like you have in your question, you can run queries that return data using ExecuteWithResults() like so:
$s = New-Object Microsoft.SqlServer.Management.Smo.Server "server instance"
$db = $s.Databases.Item("master")
$query = "SELECT * FROM [master].[sys].[databases] ORDER BY [name];"
$result = $db.ExecuteWithResults($query)
# Show output
$result.Tables[0]
I have a huge sql query where I want to run on a remote server from another server via powershell, however I am having trouble trying get the results per column per row of since test.sql produces a table with multiple table and result. I know I can query it using the
$ConnectionToServer = New-Object System.Data.SQLClient.SQLConnection
$CommandCMSQry = New-Object System.Data.SQLClient.SQLCommand
Where $CommandCMSQry contains the whole query in a string format. However, I am trying lessen the rows of the script thus I wanted to put the SQL query outside of the PS script.
$QryPath = "D:\CNA\DatabaseIntegrityCheck.sql"
invoke-expression "SQLCMD -E -S $InstanceNm -d 'master' -i $QryPath -b" | Tee-Object -Variable ResultCreateSP | Select-Object name,database_id
$ResultCreateSP
Example result:
main result
a b
1 foo1
2 foo2
and if I access the columns something with like this
write-host "a = " + $ResultCreateSP.name + "b = " + $ResultCreateSP.database_id
a = 1 b = foo1
I have converted an HTML table from this site to an XML file.
I am trying to run a SQL query in PowerShell to copy the data from from the XML file to a database table. If I run the query within SSMS, it runs fine. However when I try to run the following code in Powershell, I get:
Error: input query is too long
[string] $dbCommand =
#"
Truncate table DB_NAME.dbo.SQL_LIFE_CYCLE_UPLOAD_IC
DECLARE #Data XML
SELECT #Data = BulkColumn
FROM OPENROWSET(BULK 'D:\Powershell\Temp\SQL_Life_Cycle.XML', SINGLE_BLOB) AS x
INSERT INTO DB_NAME.dbo.SQL_LIFE_CYCLE_UPLOAD_IC
(PRODUCT_RELEASED,LIFECYCLE_START_DATE,MAINSTREAM_SUPPORT_END_DATE,EXTENDED_SUPPORT_END_DATE,SERVICE_PACK__SUPPORT_END_DATE,NOTES)
Select max(case when col=1 then value else '' end) as PRODUCT_RELEASED,
max(case when col=2 then value else '' end) as LIFECYCLE_START_DATE,
max(case when col=3 then value else '' end) as MAINSTREAM_SUPPORT_END_DATE,
max(case when col=4 then value else '' end) as EXTENDED_SUPPORT_END_DATE,
max(case when col=5 then value else '' end) as SERVICE_PACK__SUPPORT_END_DATE,
max(case when col=6 then value else '' end) as NOTES
from
(SELECT
x.y.value('Col[1]', 'int') AS [Col],
x.y.value('Row[1]', 'int') AS [Row],
x.y.value('Value[1]', 'VARCHAR(200)') AS [Value]
FROM #data .nodes('//DocumentElement/TableData') AS x ( y )
) rawTableData
group by row
having row >0
order by row
"#
OSQL.EXE -E -Q $dbCommand
Any suggestions on how to rewrite this script where it will work?
I am assuming it is too long because you are using OSQL.exe and passing it as a command line parameter. Seeing you are using powershell I would just use built in .net capabilities and execute the query in that manner. If you need more info just search the internet for .net SQL ExecuteNonQuery and it will give you a lot of results.
The basics of it are as follows:
# Instantiate new SqlConnection object.
$Connection = New-Object System.Data.SQLClient.SQLConnection
# Set the SqlConnection object's connection string to the passed value.
$Connection.ConnectionString = "place a connection string here"
# Open the connection to the database.
$Connection.Open()
# Instantiate a SqlCommand object.
$Command = New-Object System.Data.SQLClient.SQLCommand
# Set the SqlCommand's connection to the SqlConnection object above.
$Command.Connection = $Connection
# Set the SqlCommand's command text to the query value passed in.
# this is where you pass the query string you wrote to
$Command.CommandText = $dbCommand
# Execute the command against the database without returning results (NonQuery).
$Command.ExecuteNonQuery()
# Close the currently open connection.
$Connection.Close()
I have written this code a few times but I did just grab it from this script which is available on Microsoft's Technet gallery https://gallery.technet.microsoft.com/scriptcenter/Perform-ExecuteNonQuery-a05eb40a
I am trying to export the data from sql server tables to a csv file without ssms.
i am trying to achieve it by creating a stored procedure using bcp.
declare #sql nvarchar(4000);
select #sql = 'bcp "select * from table" queryout c:\file.csv -c -t, -T -S'+ ##servername
exec xp_cmdshell #sql
1 ) This query produces the expected results. But what i want is it should also include the column names in the csv files. So how can i achieve that ?
2) I want this result for all the tables in the given database. So how to do that ?
Please give some suggestions or solution as soon as possible
thanks
Only workarounds I know of...
Query the data dictionary and produce a csv field list, then
concatenate the header.csv with the data.csv. This would be querying the columns table, but you would need to take care to generate the SQL to match since you want to remove any and all chances that the column list doesn't match the data.
Create a view with the first row having all field names union all with a select on the data.
Something like:
SELECT 'a', 'b', 'c' UNION ALL SELECT a, b, c FROM table
This may require type conversions for dates, though.
I would suggest doing something along the lines of:
#echo off
bcp "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '<table_name>' AND TABLE_SCHEMA='<table_schema>'" queryout c:\file.csv -c -r, -T -S <server_name> -d <database_name>
bcp "select * from <table_schema>.<table_name>" queryout c:\data.csv -c -t, -T -S <server_name> -d <database_name>
echo. >> c:\file.csv
type c:\data.csv >> c:\file.csv
del c:\data.csv
in a .bat file.
I think that for what you want to do, it's better to just use the bcp command from a batch file/command line, instead of enabling the xp_cmdshell in SQL Server which could introduce a security issue.
Additionally, I'd like to point out that I'm not sure if the columns will always come out in the same order (in my case it did).
EDIT: Batch file explanation.
I basically ran 2 bcp commands and sent the output to 2 different files, as I couldn't find an option to append the output to another file. I then merely used the type command to add the data to the file already containing the column list, and deleted the file with the data as it is no longer needed.
Feel free to modify and mess around with it and let me know if you run into any problems.
Try this code if you want column name with SQL table data :-
public void ExportExcelFileToFolder()
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM MachineMaster"))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt, "SheetName");
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Buffer = true;
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=SqlExport.xlsx");
using (MemoryStream MyMemoryStream = new MemoryStream())
{
wb.SaveAs(MyMemoryStream);
string fileName = Guid.NewGuid() + ".xlsx";
string filePath = Path.Combine(System.Web.Hosting.HostingEnvironment.MapPath("~/ExeclFiles"), fileName);
MyMemoryStream.WriteTo(new FileStream(filePath, FileMode.Create));
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
}
}
}
}
}
}
Install-Package ClosedXML -Version 0.92.1
I am writing a powershell function to retrieve a list of students from our database but the first item returned is always the number of records. I can't figure out a way to incorporate the set nocount on into the the script - any ideas?
The function so far is:
Function CheckMIS{
$Table = new-object System.Data.DataTable
$sqlConn = new-object System.Data.SqlClient.SqlConnection("Server=blah blah")
$adapter = new-object System.Data.SqlClient.SqlDataAdapter(
"select txtSchoolID,
intSystemStatus,
txtForename, txtSurname,
txtForm
from TblPupils
where intSystemStatus = 1 ",$sqlConn)
$adapter.Fill($Table)
$sqlConn.Close()
write-output $table
}
It returns a lovely table - but the first line is always the number of records first.
I just need to suppress that output.
You could catch the rowcount for later use.
$rowCount = $adapter.Fill($Table)
Or just ignore it.
$adapter.Fill($Table) | Out-Null
Adding "Set Nocount On; select txtSchoolID,"... didn't have any effect in my test.
You should be able to just add SET NOCOUNT ON to your SQL.
i.e. SET NOCOUNT ON select txtSchoolId, intSystemStatus,
txtForename, txtSurname,
txtForm
from TblPupils
where intSystemStatus = 1