Remove column header from SQL Server query result - sql-server

I want to remove column header from SQL Server query output. I did the search but not found any solution. I have a query eg.
select cc.DepartmentID , cc.Name from HumanResources.Department cc
When I run this query I am getting output like this.
ID Name
12 Document Control
1 Engineering
16 Executive
14 Facilities and Maintenance
10 Finance
9 Human Resources
I want to remove ID and Name (Column Header) from the output in SQL Server.
I will run this query by script to generate csv file.
Edit:
When i run the query by script i got the csv file as output and it look like this.
#TYPE System.Data.DataRow
ID Name
Update:
I am putting powershell script.
$Database = "temp"
$Server = "localhost"
$AttachmentPath = "output.csv"
# Connect to SQL and query data, extract data to SQL Adapter
$SqlQuery = "select cc.DepartmentID , cc.Name from HumanResources.Department cc"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Data Source=$Server;Initial Catalog=$Database;Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$nRecs = $SqlAdapter.Fill($DataSet)
$nRecs | Out-Null
#Populate Hash Table
$objTable = $DataSet.Tables[0]
#Export Hash Table to CSV File
$objTable | Export-CSV $AttachmentPath
I want to remove column header from output.

In SSMS Under Tools/Options/Query Results/SQL Server/Results to Text there is a checkbox to 'Include column headers in the result set'. Similar for results to grid.
If you are using sqlcmd via powershell you can use /h-1 to disable the headers.
This setting corresponds to the environment variable SQLCMDHEADERS.
Tips and Tricks
Use a value of -1 to specify that no headers should be
printed. If -1 is supplied, there must be no space between the
parameter and the setting, that is, -h-1. Otherwise, SQLCMD interprets
it as a separate option and fails.
Example (modified from [TechNet])1:
sqlcmd -q /h-1 "SELECT * FROM AdventureWorks2012.Person.Person"
will also work with -h-1

In management studio at query window right click and select Query options. Look for Result>Text at a tree in the left and check out Include column headers in result set option. I think Hamlet Hakobyan is right, it is client that add column headers.

Replace your last line $objTable | Export-CSV $AttachmentPath with
$objTable | ConvertTo-Csv -NoTypeInformation | select -Skip 1 | out-file $AttachmentPath

Using the Save As option would not include the attribute (column) names.

This work correctly and column header not exists in out-file:
$workpath = "C:\myworkdir"
$InvSQLParams = #{
ServerInstance = "SQL2016"
Database = "testdb"
InputFile = "$($workpath)\selectclause.sql"
}
Invoke-Sqlcmd #InvSQLParams | ConvertTo-Csv -NoTypeInformation | select -Skip 1 | out-file "$($workpath)\result.csv"

in your script, pipe (|) the output to the "tail +3" command.
this will skip the first 2 lines of output from the SQL.

set this after connecting to database
SET HEADING OFF

Related

How to retrieve data using a SQL query that takes a list of users stored in a powershell variable as input?

I have a list of Ids in the $netid variable from the below powershell script:
$netid =Get-ADGroupMember ADGROUPSAMPLE1 | select accountname
Which stores the following in the variable:
accountname
===========
User1
User2
User3
I have a SQL Server database table which has mapping between the netid and their workstation name.
User |Machinename
------------------
User1 |laptop1
User2 |laptop2
User3 |laptop3
I'm new to powershell and thus need help with a powershell script that can help me pull the laptop names from the database for all the ids stored in the $netid variable. SQL Server version is SQL Server 2014.
Since one can use .NET objects in PowerShell, SqlClient may be used to execute a parameterized query. The example below converts the account list to json and uses OPENJSON (available in SQL 2016 and later) to parse the json list for the join to the users table. With older SQL versions, you caan similarly convert the list to XML and use XML methods to parse the XML parameter in T-SQL.
$netid = Get-ADGroupMember ADGROUPSAMPLE1 | select accountname
$accountList = $netid | ConvertTo-Json
$sql = #"
SELECT UserTable.[User], UserTable.MachineName
FROM OPENJSON(#AccountList)
WITH(
AccountName nvarchar(30) '$.accountname'
) AS AccountList
JOIN dbo.UserTable ON UserTable.[User] = AccountList.AccountName;
"#
$connection = New-Object System.Data.SqlClient.SqlConnection("Data Source=YourServer;Initial Catalog=YourDatabase;Integrated Security=SSPI")
$command = New-Object System.Data.SqlClient.SqlCommand($sql, $connection)
$sqlDataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($command)
$command.Parameters.Add("#AccountList", [System.Data.SqlDbType]::NVarChar, -1).Value = $accountList
$dataTable = New-Object System.Data.DataTable
$sqlDataAdapter.Fill($dataTable)
$dataTable | Out-GridView
$connection.Close()

Powershell script scripts on dbachecks to compare the MaxMemory of server listed in a table

Run checks against servers
Import-Module dbatools
Import-Module dbachecks
$Server = "AMCB123"
$Database = "DBA"
# Create recordset of servers to evaluate
$sconn = new-object System.Data.SqlClient.SqlConnection("server=$Server;Trusted_Connection=true");
$q = "SELECT DISTINCT servername FROM DBA.[dbo].[Server_Group] WHERE ID =1;"
$sconn.Open()
$cmd = new-object System.Data.SqlClient.SqlCommand ($q, $sconn);
$cmd.CommandTimeout = 0;
$dr = $cmd.ExecuteReader();
# Loop through the servers and build an array
while ($dr.Read()) {
Get-DbaMaxMemory -SqlServer $dr.GetValue(0) | Format-Table
}
$dr.Close()
$sconn.Close()
I have Listed the sql server(stage, prod, DR servers in a table as per the groups), Now I want to compare the servers with group id's to check wethere the servers(stage,prod, DR) with same group id is having same MAXMemory cofiguration or not.
For this I'm using the below powershell script can you please help me with this, I have created a table with all the servewith grop id.
Request to please help me with the loop thorugh the servers and build an array, so that I can run the MAXMEMORY powershell command to compare it using the group id for all servers.
I have collected all the servers details into a table dbo.server groups
the powershell script should iterate through the table by using the ID and check whether the servers in the ID group has same MAXMEMORY configuration ID server_name Environment
1 ABC0123 prod
1 ABC5123 stage
1 ABC4123 DR
2 DEF0123 prod
2 DEF5123 stage
2 DEF4123 DR
I'm trying to use a powershell script which will check and compare the MAXMEMORY configuration as per the ID(to check whether stage, prod, DR server of the same group_id have similar setting or not), if not then it will display a warning/message as group_ids servers are not configured similarly.
Please help me with the script
You're making this script longer than it needs to be. Also, you're using Format-Table prematurely - you should only use the Format-* functions for displaying final information to the user; they output strings, not properly typed data/variables that can be used down the line.
Use the tools that PowerShell and dbatools give you to get your server list, and then pass that list to Get-DbaMaxMemory as a collection.
import-module dbatools
$ServerList = Invoke-DbaSqlQuery -ServerInstance $Server -query "select distinct servername from dba.dbo.server_group where group_id = 1" | Select-Object -ExpandProperty servername;
Get-DbaMaxMemory -ServerInstance $ServerList | Select-Object SqlInstance, SqlMaxMB;
This will give you a list of your SQL instances and the memory they're configured to use. What you do after that...it's hard to say as you haven't clearly defined what you're looking for.
But this may not tell the full story. Wouldn't it be better to check the configured values and what you're currently running with? You can do that with Get-DbaSpConfigure.
import-module dbatools
$ServerList = Invoke-DbaSqlQuery -ServerInstance $Server -query "select distinct servername from dba.dbo.server_group where group_id = 1" | Select-Object -ExpandProperty servername;
Get-DbaSpConfigure -ServerInstance $ServerList | Select-Object ServerName,ConfiguredValue,RunningValue;
You can even create a computed column in that final Select-Object to tell you if the configured & running values differ.
If you just wanted to use dbachecks (which uses dbatools in the background) you can use
$ServerList = (Invoke-DbaSqlQuery -ServerInstance $Server -query "select distinct servername from dba.dbo.server_group where group_id = 1").servername
and
Invoke-DbcCheck -SQlInstance $ServerList -Check MaxMemory
Or you can set the configuration item app.computername and app.sqlinstance to your server list using
Set-DbcConfig -Name app.sqlinstance -Value $serverlist
Set-DbcConfig -Name app.computername -Value $serverlist
and then you can run this (or any other checks) using
Invoke-DbcCheck -Check MaxMemory

Powershell select value from datatable where

I have a data table that I have imported from SQL which has two columns. One is country code and the other is country name.
I have a CVS import of country names and I want to go through the data table with each country name and get its corresponding country code.
If it were SQL I could do this but I can't think how best to achieve this in PowerShell. I could of course pass each country name to SQL and query the country code but there are approx. 7000 entries in the csv file.
I have the following code which imports the csv file and I can iterate through the objects within it
$path = "C:\Temp\myImport.csv"
$import = import-csv $path
foreach($object in $import){
}
Simply execute insert for every row.
$SQLInsertFormat="insert into [table name goes there]([columns goes there]) values ({0},{1})"
$SQLConnectionString = "[connection string goes there]"
$SQLCmd = New-Object System.Data.SqlClient.SqlCommand
$SQLCmd.CommandType = [System.Data.CommandType]::Text
$SQLCmd.Connection = $SQLConnectionString
$SQLCmd.Connection.Open()
$path = "C:\Temp\myImport.csv"
$import = import-csv $path
foreach($object in $import){
$SQLCmd.CommandText = $SQLInsertFormat -f $object.CountryCode, $object.UpperCase
$SQLCmd.ExecuteNonQuery()
}
$SQLCmd.Connection.Close()

In powershell, how can I append one table to another and export to CSV?

I'm relatively new to Powershell, but here's what I'm trying to do:
I need to make multiple SQL queries and store the results to all of the queries in the same csv. With Powershell 3.0 I could use Export-CSV -Append, but unfortunately I need to use Powershell 2.0. Here is what I have right now.
#Connection Strings
$Database = "DB"
$Server = "localhost"
#Export File
$AttachmentPath = "C:\Users\Administrator\Desktop\SQLData.csv"
# Connect to SQL and query data, extract data to SQL Adapter
$SqlQuery = "select * from DB.dbo.DB1"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Data Source=$Server;Initial Catalog=$Database;Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$nRecs = $SqlAdapter.Fill($DataSet)
$nRecs | Out-Null
#Populate Hash Table
$objTable = $DataSet.Tables[0]
#Export Hash Table to CSV File
$objTable | Export-CSV $AttachmentPath
Write-Output "REPORT: Successfully created ${AttachmentPath}"
This will successfully create and export my table into a csv file that looks like this:
Table 1
----------------
col1(int) col2(string) col3(string)
col1(int) col2(string) col3(string)
but now I want to run a different query the exact same way
# Connect to SQL and query data, extract data to SQL Adapter
$SqlQuery = "select * from DB.dbo.DB2"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Data Source=$Server;Initial Catalog=$Database;Integrated Security = True"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$nRecs = $SqlAdapter.Fill($DataSet)
$nRecs | Out-Null
#Populate Hash Table
$objTable = $DataSet.Tables[0]
#IN POWERSHELL 3.0 THIS WOULD WORK
$objTable | Export-CSV $AttachmentPath -Append
and append it onto the first table. The final CSV would look like this:
Table 1
----------------
col1(int) col2(string) col3(string)
col1(int) col2(string) col3(string)
Table 2
----------------
col1(string) col2(int) col3(int)
col1(string) col2(int) col3(int)
I can't find any way to do this, any help is appreciated!
EDIT
Found a workaround by exporting the second query to a csv,
$objTable | Export-CSV $AttachmentPath
Then I used the Get-Content and Add-Content cmdlets to append to the first csv. It's hacky but it works. If you have anything better let me know!
$file2=Get-Content $AttachmentPath
Add-Content "SQLData.csv" "`n"
Add-Content "SQLData.csv" $file1
Why can't you use UNION in your query like below to get a merged data from both table
$SqlQuery = "select * from DB.dbo.DB1 UNION select * from DB.dbo.DB2"
Then you can use Export-CSV filename.csv commandlet to export the data to a CSV file (OR) see this thread How to export data to CSV in PowerShell?
While Union might not be acceptable for all situations, it is possible to merge two queries... just cast the output of numbers and dates to varchar/char.
SELECT Cast(col1(int) as varchar(7)) as col1, col2(string) as col2,
col3(string)
FROM [Table 1]
UNION ALL SELECT col1(string), Cast(col2(int) as varchar(7)),
Cast(col3(int) as varchar(7))
Just make sure you aren't truncating any data and you can mash em together.
Of course with 15 tables joining them in powershell would seem easier to maintain.

How can I create a database table from a system.Data.datatable object?

Let us assume, that I have the following PowerShell code:
$connectionstring = "... some connection ..."
$sql = "Select * from Sometable"
$tablename= 'Copy_of_Sometable'
$cmd = New-Object system.Data.OleDb.OleDbCommand($sql,$connectionstring)
$da = New-Object system.Data.OleDb.OleDbDataAdapter($cmd)
$dt = New-Object system.Data.datatable
[void]$da.fill($dt)
I know, that I can derive a create table script from $dt and use it to create a new table with a given name cf. for example.
But is there a more direct way to create a new table with a supplied name (empty or already filled) from the datatable object?
I created a function called add-sqltable which will take a datatable as input and create a SQL Server table using SMO.
The function is available on PoshCode and Scripting Guy Script Repository. I blogged about it for a Scripting Guy guest post.
Using a System.Data.Datatable you pretty much have to use the method described.
However a more direct method is available if you're using SQL 2008. The Invoke-SqlCmd cmdlet will let you do as Ekkehard.Horner suggested SELECT * INTO newtable FROM oldtable. (sadly copy-item isn't supported)
Of course the system.Data.OleDb.OleDbCommand works to do the same thing.
Depending on the driver's capabilities, you may succeed with a single SQL statement like:
"SELECT * INTO newtable FROM oldtable"
With ODBC and Jet the tables may even be IN (keyword) different databases.
Because I really like the "INSERT/SELECT INTO IN" command(s) and never before used Powershell for database 'work':
(Edited) Powershell session:
PS C:\Documents and Settings\eh\My Documents\WindowsPowerShell>
$CS="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<SOMEWHERE>\Nwind.mdb"
$SQL="SELECT * INTO CusCopy FROM Customers"
$cmd = New-Object system.Data.OleDb.OleDbCommand($SQL,$CS)
$cmd.Connection.Open()
$cmd.ExecuteNonQuery()
91
Please take the "91" as evidence that the command affected==inserted the 91
customers from the original table to the copy.
$SQL="SELECT * INTO [customer.csv] IN '' 'text;HDR=YES;Database=<SOMEWHERE>' FROM Customers"
$cmd = New-Object system.Data.OleDb.OleDbCommand($SQL,$CS)
$cmd.Connection.Open()
$cmd.ExecuteNonQuery()
91
dir
Directory: <SOMEWHERE>
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 14.02.2011 22:09 13395 customer.csv
-a--- 14.02.2011 22:01 2576384 Nwind.mdb
-a--- 14.02.2011 22:09 394 schema.ini
A table .csv and a schema.ini (entry) were newly/dutifully created.

Resources