I want to loop through a result set in SQL. So far I only know how to do this in powershell. See below:
foreach ($TestName in $DSFailures | % {$_.TestName}) {
$Query= "USE TestDS
insert into #temptable
SELECT space(iteration * 4) + TheFullEntityName + ' (' + rtrim(TheType) + ')' as EntityName, *
FROM dbo.fn_DependantObjects('$TestName', 1, 0)
ORDER BY ThePath"
Invoke-Sqlcmd -ServerInstance "SQL2016" -Database "db" -Query $Query
How can I achieve this in SQL?
Here is the answer:
Function Get-FunctionDependencies{
$FPM_Functions = "select replace (name, '_CLR','') AS FPM_FunctionName
into #temptable1
from sys.objects
where name like 'fn_clr%'
select * from #temptable1"
$GetCLRCallingFunctions = Invoke-Sqlcmd -ServerInstance "sql" -Database "DB" -Query $FPM_Functions
foreach ($FPM_FunctionName in $GetCLRCallingFunctions | % {$_.FPM_FunctionName}) {
Write-Output "--These are the dependencies for $FPM_FunctionName"
$query1 = " SELECT referencing_entity_name as [FPM Function Dependencies] FROM sys.dm_sql_referencing_entities ('dbo.$FPM_FunctionName', 'OBJECT');"
Related
Basically, I want the data to show up in an excel file like it shows in the SQL database.
This is much more simplified version of the work that I need to do but in essence this what it is.
I retrieve the data from SQL and for each item retrieved(which is the primary key) I want the data corresponding to it to be added in the hashtable. I then export this hashtable as a CSV
The CSV file is generated but with some weird data
I am not sure what exactly is wrong because when I Write-host $hashObject I can see the data is in there.
Code
$server = "DESKTOP\SQLEXPRESS"
$database = "AdventureWorks2019"
$hashTable = #{}
$hashObject = #([PSCustomObject]$hashTable)
$query = "SELECT[DepartmentID] FROM [AdventureWorks2019].[HumanResources].[Department]"
$invokeSql = Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $query
$departmentResult = $invokeSql.DepartmentID
ForEach($department in $departmentResult){
$queryAll = "SELECT [Name],[GroupName],[ModifiedDate]FROM [AdventureWorks2019].[HumanResources].[Department] Where DepartmentID=$department"
$invokeSql = Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $queryAll
$name = $invokeSql.Name
$groupName = $invokeSql.GroupName
$modifiedDate = $invokeSql.ModifiedDate
$hashObject+=("Department",$department, "Name",$name,"GroupName",$groupName,"ModifiedDate",$modifiedDate)
}
ConvertTo-Csv $hashObject| Export-Csv -Path "C:\Users\Desktop\PowerShell\HashTable_OutputFiles\HashOutput.csv"
This is a simplified version of what you're attempting to do, in this case you should be able to use the SQL IN Operator in your second query instead of querying your Database on each loop iteration.
As aside, is unclear what you wanted to do when declaring a hash table to then convert it to a PSCustomObject instance and then wrap it in an array:
$hashTable = #{}
$hashObject = #([PSCustomObject] $hashTable)
It's also worth noting that ConvertTo-Csv and Import-Csv are coded in such a way that they are intended to receive objects from the pipeline. This answer might help clarifying the Why. It's also unclear why are you attempting to first convert the objects to Csv and then exporting them when Import-Csv can (and in this case, must) receive the objects, convert them to a Csv string and then export them to a file.
$server = "DESKTOP\SQLEXPRESS"
$database = "AdventureWorks2019"
$query = "SELECT [DepartmentID] FROM [AdventureWorks2019].[HumanResources].[Department]"
$invokeSql = Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $query
$department = "'{0}'" -f ($invokeSql.DepartmentID -join "','")
$query = #"
SELECT [Name],
[GroupName],
[ModifiedDate]
FROM [AdventureWorks2019].[HumanResources].[Department]
WHERE DepartmentID IN ($department);
"#
Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $query |
Export-Csv -Path "C:\Users\Desktop\PowerShell\HashTable_OutputFiles\HashOutput.csv"
If you want to query the database per ID from the first query, you could do it this way (note this is similar to what you where looking to accomplish, merge the ID with the second results from the second query):
$invokeSql = Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $query
$query = #"
SELECT [Name],
[GroupName],
[ModifiedDate]
FROM [AdventureWorks2019].[HumanResources].[Department]
WHERE DepartmentID = '{0}';
"#
& {
foreach($id in $invokeSql.DepartmentID) {
$queryID = $query -f $id
Invoke-Sqlcmd -ServerInstance $server -Database $database -Query $queryID |
Select-Object #{ N='DepartmentID'; E={ $id }}, *
}
} | Export-Csv -Path "C:\Users\Desktop\PowerShell\HashTable_OutputFiles\HashOutput.csv"
I have the below code to get data from a SQL DB and export it into a CSV file:
#Server and Database names
$SQLServer = "Servername"
$DB = "DatabaseName"
#SQL Command
$FullScriptSQL="Select * from MyTable WHERE Column = 'TestData'"
#Invoke the command, rename the column headers and export to CSV file
$FullScriptCallLinked = Invoke-Sqlcmd -ServerInstance $SQLServer -Database $DB -Query $FullScriptSQL | select-object #{ expression={$_.Column1};label='Column1 Name'},#{ expression={$_.Column2};label='Column2 Name'},#{ expression={$_.Column3}; label='Column3 Name' },#{ expression={$_.Column4} ; label='Column4 Name' }
Export-CSV -Path ".\ResultFile\FullScript.csv" -inputobject $FullScriptCallLinked -Append -NoTypeInformation
This works perfectly if there is one result. But if there is more than one result, it will show the below in the csv file
I am at my wits end as to why it is doing this. It's obviously the DB parameter data or something to that effect. Been googling for a few days with no luck. Anyone smarter than I able to assist please?
Instead of using Select-Object to rename your columns, which is quite inefficient, you could give the alias to your columns on the query itself:
$SQLServer = "Servername"
$DB = "DatabaseName"
$query = #'
SELECT Column1 AS "Column1 Name",
Column2 AS "Column2 Name",
Column3 AS "Column3 Name",
Column4 AS "Column4 Name"
FROM MyTable
WHERE ColumnX = 'TestData'
'#
Invoke-Sqlcmd -ServerInstance $SQLServer -Database $DB -Query $query |
Export-CSV -Path ".\ResultFile\FullScript.csv" -NoTypeInformation
Also, as in my comment, the code you have on your question is fine and should work, the only problem was using -InputObject instead of piping the results to Export-Csv:
$FullScriptCallLinked | Export-Csv -Path ".\ResultFile\FullScript.csv" -NoTypeInformation
Figured it out. I knew I was close!
#Server and Database names
$SQLServer = "Servername"
$DB = "DatabaseName"
#SQL Command
$FullScriptSQL="Select * from MyTable WHERE Column = 'TestData'"
#Invoke the command, rename the column headers and export to CSV file
$FullScriptCallLinked = Invoke-Sqlcmd -ServerInstance $SQLServer -Database $DB -Query $FullScriptSQL
foreach($i in $FullScriptCallLinked){
select-object #{ expression={$_.Column1};label='Column1 Name'},#{ expression={$_.Column2};label='Column2 Name'},#{ expression={$_.Column3}; label='Column3 Name' },#{ expression={$_.Column4} ; label='Column4 Name' }
Export-CSV -Path ".\ResultFile\FullScript.csv" -inputobject $i -Append -NoTypeInformation
}
The Invoke-Sqlcmd doesn't return data in rows, it lists each item separately
This is the code that I'm using:
Invoke-Sqlcmd -ServerInstance "MyServer" -Query "SELECT * FROM [MyDB].[dbo].[MyTable]"
I get something like this:
Key : 81839
Type : DELETE
TableName : InstList
ColumnName : Key
ID : 1092110700485
OldValue : 5216268
NewValue :
UpdateDate : 7/22/2019 12:06:30 PM
UserName : test
FeatureName : Instruments
Key : 81840
Type : DELETE
TableName : InstList
ColumnName : Key
ID : 2101128532011
OldValue : 5289370
NewValue :
UpdateDate : 7/22/2019 12:06:30 PM
UserName : test
FeatureName : Instruments
Why does it not come out in rows?
Why does it not come out in rows?
It is only matter or presenting data:
Invoke-Sqlcmd -ServerInstance "MyServer" -Query "SELECT * FROM [MyDB].[dbo].[MyTable]"
| out-gridview
or:
Invoke-Sqlcmd -ServerInstance "MyServer" -Query "SELECT * FROM [MyDB].[dbo].[MyTable]"
| Format-Table -AutoSize
I have a user table in the database that i am trying to update with Createdon date and disabled on date with the data from Active Directory. So far this is what I have:
$SearchRoot = "OU=NonAIQ,OU=FrontOffice,DC=dev,DC=local"
$serverName = "localhost"
#$SearchRoot = "OU=NonAIQ,OU=FrontOffice,DC=dmz,DC=local"
#$serverName = "spoproddb3.dmz.local"
try {
Import-Module "sqlps" -DisableNameChecking
if ((Get-PSSnapin -Name "Quest.ActiveRoles.ADManagement" -ErrorAction SilentlyContinue) -eq $null ) {
Add-PsSnapin "Quest.ActiveRoles.ADManagement"
}
$externalUsers = Get-QADUser -SizeLimit 0 -SearchRoot $SearchRoot | Select-Object whencreated, whenchanged
$externalUsers | % {
$query = #"
Update tbl_EdgeUsers Set CompanyName = '$_.CreationDate'
Where UserUPN = $_.UserPrincipalName;
"#
Write-Host "The query is $query"
Invoke-SqlCmd -ServerInstance $serverName -Query $query -Database "EdgeDW"
}
} finally {
Remove-Module "sqlps" -ErrorAction SilentlyContinue
Remove-PsSnapin "Quest.ActiveRoles.ADManagement"
}
Now for when created, we just grab all the values.
But since AD does not track the Disabled in date, I am using the when changed date since we dont make changes to an account once it is changed.
The part that I am stuck on is about the logic for when changed date. For this I have to check if an account is disabled. If it is the update the table with that date. If an account is not disabled, then ignore that value and set the value in the sql table as '1/1/9999'.
can you guys please help with this logic?
Thank you in advance for any help.
of top of my head maybe something such as this, although thinking about it now, its a nasty way having the invoke-sql inside the foreach loop if the dataset is large, probably better to output the results of the if statement to csv or somewhere then run the invoke-sql against that.
$users = Get-ADUser -Filter * -Properties whenchanged | Select-Object -Property UserPrincipalName, whenchanged, enabled
$disabledsql = #"
update tbl_EdgeUsers Set date = '$user.whenchanged'
Where UserUPN = '$user.UserPrincipalName';
"#
$activesql = #"
update tbl_EdgeUsers Set date = '1/1/9999
Where UserUPN = '$user.UserPrincipalName';
"#
foreach ($user in $users)
{
if ($user.enabled -eq 'False')
{
Invoke-Sqlcmd -ServerInstance $serverName -Query $disabledsql -Database 'EdgeDW'
}
else
{
Invoke-Sqlcmd -ServerInstance $serverName -Query $activesql -Database 'EdgeDW'
}
}
I have a database table with an event_id column and a scheduled_at column.
The query is called in php and is as such:
$columnName = 'scheduled_at';
$start = '2013-02-26';
$end = '2013-02-27';
// query to be executed
$sql = ( SELECT * FROM $table WHERE $columnName BETWEEN $start AND $end );
The query does not work when executed, however the following does work
$sql = ( SELECT * FROM $table WHERE $columnName BETWEEN $start AND '2013-02-27' );
and
$sql = ( SELECT * FROM $table WHERE $columnName BETWEEN $start AND $start );
does not work, but the following does work
$sql = ( SELECT * FROM $table WHERE $columnName BETWEEN '2013-02-27' AND '2013-02-27' );
Inserting the value manually makes it work but loses the usefulness of the function. Any ideas why it would not work?
you need to quote your variables, so that the SQL string that is created containes quotes around the date values. eg
$sql = "( SELECT * FROM $table WHERE $columnName BETWEEN '$start' AND '$end' )";