SQL Server Agent job history to HTML report - html

I am trying to output SQL Server Agent job history into an HTML report and send it to mail as a check in office.
Here's my code:
$tabName = "Report"
$table = New-Object system.Data.DataTable "$tabName"
$col1 = New-Object system.Data.DataColumn "Server",([string])
$col2 = New-Object system.Data.DataColumn "Job Name",([string])
$col3 = New-Object system.Data.DataColumn "Step Name",([string])
$col4 = New-Object system.Data.DataColumn "Message",([string])
$col5 = New-Object system.Data.DataColumn "RunDate",([string])
$table.columns.add($col1)
$table.columns.add($col2)
$table.columns.add($col3)
$table.columns.add($col4)
$table.columns.add($col5)
$data = (Get-SqlAgentJobHistory -ServerInstance SQLServ1 -JobName "syspolicy_purge_history" -Since Yesterday | Select-Object Server, JobName, StepName, Message, RunDate )
$row = $table.NewRow()
$row."Server" = ($data."Server")
$row."Job Name" = ($data."JobName")
$row."Step Name" = ($data."StepName")
$row."Message" = ($data."Message")
$row."RunDate" = ($data."RunDate")
$table.Rows.Add($row)
$Head = #"
<style>
body {
font-family: "Arial";
font-size: 8pt;
color: #4C607B;
}
th, td {
border: 1px solid #e57300;
border-collapse: collapse;
padding: 5px;
}
th {
font-size: 1.2em;
text-align: left;
background-color: #003366;
color: #ffffff;
}
td {
color: #000000;
}
.even { background-color: #ffffff; }
.odd { background-color: #bfbfbf; }
</style>
"#
$Report = [string]$body = [PSCustomObject]$table | select-Object Server, JobName, StepName, Message, RunDate | ConvertTo-HTML -head $Head -Body "<font color=`"Black`"><h4>SQL Job History</h4></font>" | Out-File "C:\Users\Administrator\Documents\scripts\sql job history\report.html"
The HTML fields I've added display when I output the report but not the content.
Any advise on this one please?

You need to foreach over the results from Get-SqlAgentJobHistory, eg
foreach ( $r in $data )
{
$row = $table.NewRow()
$row."Server" = ($r."Server")
$row."Job Name" = ($r."JobName")
$row."Step Name" = ($r."StepName")
$row."Message" = ($r."Message")
$row."RunDate" = ($r."RunDate")
$table.Rows.Add($row)
}

Try the code below. It sends an email with jobs information for the last 24 hours.
Just replace 'email_recipients_list' and 'url_to_ssis_jobs_monitoring_report' with relevant values.
DECLARE
#email_recipients VARCHAR(128)
, #email_subject NVARCHAR(128)
, #email_body_format VARCHAR(128)
, #email_body NVARCHAR(MAX)
, #job_count INT
, #table_style VARCHAR(512)
, #from datetime
, #periode NVARCHAR(512)
, #url_to_ssis_jobs_monitoring_report VARCHAR(128)
SET #email_recipients='email_recipients_list'
SET #email_body_format='HTML'
SET #table_style = 'cellpadding="2" cellspacing="2" border="1" style="border-collapse: collapse; border: 1px solid black;"';
SET #from = DATEADD(day, -1, getdate())
SET #periode = 'between ' + FORMAT(DATEADD(d, -1, GETDATE()), 'yyyy-MM-dd HH:MM:ss') + ' and ' + FORMAT(GETDATE(), 'yyyy-MM-dd HH:MM:ss')
SET #email_subject = 'SSIS Jobs ' + #periode
SET #url_to_ssis_jobs_monitoring_report = 'url_to_ssis_jobs_monitoring_report'
DECLARE #job_table NVARCHAR(MAX)
DECLARE #job TABLE(
[Start time] NVARCHAR(19)
, [Job] NVARCHAR(128)
, [Job execution status] NVARCHAR(128)
, [Execution time] NVARCHAR(8)
);
WITH subset As (
SELECT
CAST(left(t1.run_date,8) As DATETIME) + CAST(STUFF(STUFF(RIGHT('000000'+ISNULL(CAST(t1.run_time As NVARCHAR(6)),''),6),5,0,':'),3,0,':') As datetime) As [Start time]
, t1.job_id As 'Id Job'
, t1.name As Job
, CASE IIF(MIN(t2.run_status) = 1, MAX(t2.run_status), MIN(t2.run_status))
WHEN 0 THEN 'Failed'
WHEN 1 THEN 'Succeeded'
WHEN 2 THEN 'Retry'
WHEN 3 THEN 'Canceled'
WHEN 4 THEN 'In Progress'
ELSE 'Unknown'
END As [Status]
, CONVERT(TIME(0), DATEADD(SECOND,
SUM(
DATEDIFF(SECOND,0,CAST(CAST(STUFF(STUFF(RIGHT('000000'+ISNULL(CAST(t2.run_duration As NVARCHAR(6)),''),6),5,0,':'),3,0,':') As TIME) As DATETIME))
)
, 0)
) As 'Execution time'
FROM (
SELECT
sjh.job_id
,sj.name As name
,sjh.run_date
,sjh.run_time
,LEAD(sjh.run_time,1) OVER ( ORDER BY run_date, run_time) As next_run_time
,MIN(sjh.run_status) As run_status
FROM [msdb].[dbo].[sysjobhistory] sjh
LEFT JOIN [msdb].[dbo].[sysjobs] sj
ON sjh.job_id = sj.job_id
WHERE
sjh.step_id = 1
-- To exclude unrelevant jobs
AND TRY_CONVERT(UNIQUEIDENTIFIER,sj.name) IS NULL
GROUP BY sjh.job_id, sj.name, sjh.run_date, sjh.run_time
) t1
LEFT JOIN [msdb].[dbo].[sysjobhistory] t2
ON
t2.job_id = t1.job_id
AND t2.run_date = t1.run_date
WHERE
t2.job_id = t1.job_id
AND t2.run_date = t1.run_date
AND t2.step_id <> 0
AND CAST(left(t1.run_date,8) As datetime) + CAST(STUFF(STUFF(RIGHT('000000'+ISNULL(CAST(t1.run_time As NVARCHAR(6)),''),6),5,0,':'),3,0,':') As datetime) > #from
-- To exclude unrelevant jobs
AND TRY_CONVERT(UNIQUEIDENTIFIER,t1.name) IS NULL
GROUP BY t1.job_id, t1.run_date, t1.run_time, t1.name, t1.next_run_time
)
INSERT INTO #job
SELECT
FORMAT(s.[Start time], 'yyyy-MM-dd HH:MM:ss') As [Start time]
, s.Job
, s.Status
, CAST(s.[Execution time] As NVARCHAR(8)) As [Execution time]
FROM subset s
SET #job_count = ##ROWCOUNT
If #job_count > 0
BEGIN
SET #job_table = CAST( (
SELECT td = [Start time] + '</td><td>' + [Job] + '</td><td>' + [Job execution status] + '</td><td>' + [Execution time]
FROM (
SELECT *
FROM #job
) As d
ORDER BY [Start time]
FOR XML PATH( 'tr' ), TYPE ) As NVARCHAR(MAX) )
set #job_table = '<table ' + #table_style + '>'
+ '<tr><th>Start time</th><th>Job</th><th>Job execution status</th><th>Execution time</th></tr>'
+ replace( replace( #job_table, '<', '<' ), '>', '>' )
+ '</table>'
SET #email_body = #job_table
END
SET #email_body = '<h1>SSIS Jobs ' + #periode + '</h1>' + #email_body
SET #email_body = #email_body + '<br><br>SSIS jobs monitoring report'
-- Send email
EXEC msdb.dbo.sp_send_dbmail
#recipients=#email_recipients
, #body=#email_body
, #subject=#email_subject
, #body_format=#email_body_format

Related

am I using </table> wrong?

`I am creating an automatic mail using de msdb function but when the sql is converted to HTML and send in outlook the table data rows keep adding and outlook crashes.
while only one row is expected, as shows when I just run the query.
This is what I have at this moment
DECLARE #tableHTML NVARCHAR(max) = '';
SET #tableHTML =
'<h1>Picking en Rework</h1>' +
'<table border="1">' +
'<tr>' +
'<th>Order ETA</th>' +
'<th>To be Picked</th>' +
'<th>Rework Actions</th>' +
'<th>Destination Plts req order-line</th>' +
'<th>Destination Plts Req Total</th>' +
'<th>Reworked Plts On Stock</th>' +
'<th>Plts Left To Rework Order-Line</th>' +
'<th>Plts Left To Rework total</th>' +
'</tr>' +
CAST
(
(
SELECT
td = coalesce(vOuttakeOrderHeaders_2057.[ETA], ''), '',
td = coalesce([To be Picked], ''), '',
td = coalesce(vReworkReq_2057.[Rework Actions], ''), '',
td = coalesce(vReworkReq_2057.[Destination Plts Req Order-Line],
''),'',
td = coalesce(vReworkReq_2057.[Destination Plts Req total], ''), '',
td = coalesce(vReworkReq_2057.[Reworked Plts On Stock], ''), '',
td = coalesce(vReworkReq_2057.[Plts Left To Rework Order-Line], ''),
'',
td = coalesce(vReworkReq_2057.[Plts Left To Rework total], ''), ''
FROM [dbo].[vMailReworkPicking_2057], vOuttakeOrderDetails_2057
left join vOuttakeOrderHeaders_2057 on
vOuttakeOrderDetails_2057.iOrderHeaderSysID =
vOuttakeOrderHeaders_2057.iOrderHeaderSysID
left join vReworkReq_2057 on vOuttakeOrderDetails_2057.Article =
vReworkReq_2057.Article
left join vMailReworkPicking_2057 on vOuttakeOrderHeaders_2057.[ETA] =
vMailReworkPicking_2057.[Order ETA]
Where
vOuttakeOrderHeaders_2057.[Order Type] like 'outtake'
and DisposedQuantity < TargetQuantity
and RestPick > 0
ORDER BY vOuttakeOrderHeaders_2057.[ETA] DESC
FOR XML PATH('tr'), type) as nvarchar(max)) +
'</table>';
EXEC msdb.dbo.sp_send_dbmail
#profile_name = 'test123',
#recipients = 'email',
#subject = 'Picking & Rework',
#body = #tableHTML,
#body_format = 'HTML';`

SSRS Download All History Snapshots

Is it possible to download all the history snapshots of a report at once? Preferably as a CSV. Would save a lot time instead of clicking into each one individually and selecting save as CSV.
I only see the option to Delete
In PowerShell, you can loop through each snapshot and save them using this example:
<#
Description: Save SSRS Report Snapshots
#>
$sql = "
DECLARE #ReportName NVARCHAR(200) = 'Your Report Name'; --change to NULL for every snapshot
DECLARE #FileFormat NVARCHAR(50) = 'CSV'; --HTML5,PPTX,ATOM,HTML4.0,MHTML,IMAGE,EXCEL (for .xls),EXCELOPENXML (for .xlsx),WORD (for .doc),WORDOPENXML (for .docx),CSV,PDF,XML
DECLARE #FileExtn NVARCHAR(50) = 'csv';
DECLARE #ServerName NVARCHAR(100) = 'http://YourServerName';
DECLARE #DateFrom DATE = CAST(DATEADD(DAY, -1, GETDATE()) AS DATE); --change to NULL for every snapshot
DECLARE #ExportPath NVARCHAR(200) = 'C:\Temp\';
SELECT
--[ReportID] = [c].[itemid]
-- , [ReportName] = [c].[name]
-- , [ReportPath] = [c].[path]
-- , [SnaphsotDate] = FORMAT([h].[snapshotdate], 'dd-MMM-yyyy')
-- , [SnapshotDescription] = [s].[DESCRIPTION]
-- , [SnapshotEffectiveParams] = [s].[effectiveparams]
-- , [SnapshotQueryParams] = [s].[queryparams]
-- , [ScheduleName] = [sc].[name]
-- , [ScheduleNextRunTime] = CONVERT(VARCHAR(20), [sc].[nextruntime], 113)
[ExportFileName] = #ExportPath + REPLACE([c].[name], ' ', '_') + '_' + FORMAT([h].[snapshotdate], 'yyyyMMdd_HHmm') + '.' + #FileExtn
, [SnapshotUrl] =
#ServerName
+ '/ReportServer/Pages/ReportViewer.aspx?'
+ [c].[path] + '&rs:Command=Render&rs:Format='
+ #FileFormat + '&rs:Snapshot='
+ FORMAT([h].[snapshotdate], 'yyyy-MM-ddTHH:mm:ss')
FROM
[ReportServer].[dbo].[History] AS [h] WITH(NOLOCK)
INNER JOIN [ReportServer].[dbo].[SnapshotData] AS [s] WITH(NOLOCK) ON [h].[snapshotdataid] = [s].[snapshotdataid]
INNER JOIN [ReportServer].[dbo].[Catalog] AS [c] WITH(NOLOCK) ON [c].[itemid] = [h].[reportid]
INNER JOIN [ReportServer].[dbo].[ReportSchedule] AS [rs] WITH(NOLOCK) ON [rs].[reportid] = [h].[reportid]
INNER JOIN [ReportServer].[dbo].[Schedule] AS [sc] WITH(NOLOCK) ON [sc].[scheduleid] = [rs].[scheduleid]
WHERE
1=1
AND [rs].[reportaction] = 2
AND (#ReportName IS NULL OR [c].[Name] = #ReportName)
AND (#DateFrom IS NULL OR [h].[snapshotdate] >= CAST(DATEADD(DAY, -1, GETDATE()) AS DATE))
ORDER BY
[c].[name]
, [h].[snapshotdate];
;"
$server = 'YourServerName';
$dbs = 'MASTER';
$dsn = "Data Source=$server; Initial Catalog=$dbs; Integrated Security=SSPI;";
$cn = New-Object System.Data.SqlClient.SqlConnection($dsn);
#execute merge statement here with parameters
$cn = New-Object System.Data.SqlClient.SqlConnection($dsn);
$cn.Open();
$cmd = $cn.CreateCommand();
$cmd.CommandText = $sql
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $cmd
$cmd.Connection = $cn
$ds = New-Object System.Data.DataSet
$SqlAdapter.Fill($ds)
$cn.Close()
$Result = $ds.Tables[0]
Foreach ($item in $Result)
{
#Write-Host $item.name
$SnapshotUrl = $item.SnapshotUrl
$ExportFileName = $item.ExportFileName
(Invoke-WebRequest -Uri $SnapshotUrl -OutFile $ExportFileName -UseDefaultCredentials -TimeoutSec 240);
}
https://learn.microsoft.com/en-us/sql/reporting-services/url-access-parameter-reference?view=sql-server-ver15
Was having trouble with powershell, so thought I'd post simplified version of my rough Python solution inspired by the resource from #aduguid's answer.
import requests
from requests_negotiate_sspi import HttpNegotiateAuth
import os
def downloadFile(url, file_name, download_folder, session):
response = session.get(url, stream=True) # open the download link
file_path = os.path.join(download_folder, file_name)
with open(file_path, 'wb') as file: # create a new file with write binary mode
for chunk in response.iter_content(chunk_size=1024):
if chunk:
file.write(chunk)
# Can also use '/Reports()' for non-linked reports.
# Can also pass in 'path="<report_path>"' instead of using id numbers,
# e.g. '.../Reports(path="/cool%20reports/my%20report")/HistorySnapshots'
api_url = r'http://<server_name>/reports/api/v2.0/LinkedReports(<item_id>)/HistorySnapshots'
session = requests.session()
session.auth = HttpNegotiateAuth() # uses windows log in
response = session.get(api_url)
hs_snapshot_list = response.json()['value']
for item_dict in hs_snapshot_list:
download_url = (r'http://<server_name>/ReportServer/Pages/ReportViewer.aspx?<report_path>'
+ '&rs:Snapshot=' + item_dict['HistoryId']
+ '&rs:Format=CSV')
downloadFile(download_url, '<your_file_name>', '<your_download_folder>', session)
SSRS API Resource:
https://app.swaggerhub.com/apis/microsoft-rs/SSRS/2.0#/Reports/GetReportHistorySnapshots

Tweepy information into MySQL - text being cut off

I am inserting information from twitter using Tweepy into a MySQL table. Mostly it works are intended however, the actual text from the tweet is being cut off and many end with "..." and I am not sure why this is.
An example of the output is this:
#JamesMelville: Remain voters are not "unpatriotic" by "talking the country down".Its the opposite. Remainers care about Britains fut…
Thanks for your help
Here is my stream listener class: (I am new to python so this is probably poor)
class listener(StreamListener):
def on_data(self, data):
try:
jsonData=json.loads(data)
tweets =(jsonData['text'])
if tweets.startswith('RT'):
retweets = True
else:
retweets = False
tweets = tweets.replace('RT', '')
tweets = tweets.replace("'", '')
tweets = tweets.lstrip()
tweets = tweets.replace('\n', '')
screen_name =(jsonData['user']['screen_name'])
name =(jsonData['user']['name'])
name = name.replace(',', ' ')
language =(jsonData['lang'])
location =(jsonData['place'])
coord =(jsonData['coordinates'])
device = jsonData['source'].split('">')[1].replace('</a>', '')
tweettime = jsonData['created_at'].replace('+', '')
tweettime = datetime.datetime.strptime(tweettime, "%a %b %d %H:%M:%S %f %Y")
date_to_string = str(tweettime.strftime("%Y/%m/%d,%H:%M:%S"))
date_created = date_to_string.split(',')[0]
time_created = date_to_string.split(',')[1]
created_time =(time_created)
created_date =(date_created)
htext = jsonData['entities']['hashtags']
htext2 = []
hashtag_list = ''
for hashtag in htext:
htext=str(hashtag['text'])
hashtag_list = hashtag_list + ' ::' + htext
hashtag_list = hashtag_list.replace("'", "")
conn = connect( host = '', port = , user = ', passwd = '', charset='utf8', autocommit = True);
conn.commit()
cursor = conn.cursor( cursors.DictCursor );
cursor.execute("CREATE DATABASE IF NOT EXISTS twitter")
cursor.execute("USE twitter")
cursor.execute( """CREATE TABLE IF NOT EXISTS `twitter_data`(ID INT AUTO_INCREMENT NOT NULL,`Name` VARCHAR( 200 ) ,`Screen name` VARCHAR( 200 ) , `Date created` VARCHAR ( 20 ), `Time created` VARCHAR ( 8 ), Tweet VARCHAR ( 200 ), Hashtags VARCHAR ( 200 ), Retweets VARCHAR ( 5 ), Lanugage VARCHAR ( 20 ), Device VARCHAR ( 60 ), Location VARCHAR( 200 ), Coordinates VARCHAR ( 200 ), PRIMARY KEY ( ID ))""" )
sql = "INSERT INTO `twitter_data` VALUES( Null, '" + str(name) + "', '" + str(screen_name) + "', '" + str(created_date) + "', '" + str(created_time) + "', '" + str(tweets) + "', '" + str(hashtag_list) + "', '" + str(retweets) + "', '" + str(language) + "', '" + str(device) + "', '" + str(location) + "', '" + str(coord) + "') "
print(sql)
cursor.execute(sql)
return True
except Exception as N:
print('failed on_data '+ str(N))
time.sleep(5)
I have found a solution to my question.
The text was being truncated when it was a retweet due to the 140 character limit.
Therefore it from nothing to do with MySQL.
My solution was to use the 'retweet_status' attribute (and split out the actual tweet text part) rather than 'text' if the tweet was a retweet, otherwise I just used 'text'.
Here is some of the code that was changed:
if tweets.startswith('RT'):
retweets = True
tweets = str(jsonData['retweeted_status']).split('\'text\':')[1]
if 'display_text_range' in tweets:
tweets = tweets.split(', \'display_text_range\'')[0]
else:
tweets = tweets.split(', \'source\'')[0]
else:
retweets = False
tweets = tweets.replace('RT', '')

MySQL Query with dynamic column name

I have a source table with these columns:
I also have a destination table like this:
The destination table has 1440 rows, with the minute column filled in (1 row for each minute in the day).
For each row in the source table, I need to fill in a "1" in the destination table for the appropriate channel (there are 10 channels total), for every minute between the StartTime and FinishTime.
I'm just doing this in MySQL Workbench (it's a one-time query). What is my beast approach?
Thanks,
-Scott
Pseudo-code:
SELECT DISTINCT ChannelNumber
FROM source
while ($row = fetch_assoc()) {
$channel_col = 'ch'.$row['ChannelNumber']
$sql = "
UPDATE destination
JOIN source ON StartTime = destination.minutes
AND source.ChannelNumber = $row[ChannelNumber]
SET destination.$channel_col = 1
";
query($sql);
}
Normally you have to be concerned about dynamically creating a string which becomes an SQL query to avoid SQL injection, but since all the data is coming from within your database it shouldn't be a problem.
Here is an MySQL solution:
CREATE PROCEDURE PopulateDestinationTable()
BEGIN
DECLARE i INT DEFAULT 0;
DECLARE n INT DEFAULT 0;
DECLARE CNumber INT DEFAULT 0;
DECLARE STime INT DEFAULT 0;
DECLARE FTime INT DEFAULT 0;
SELECT COUNT(*) FROM SourceTable INTO n;
SET i = 0;
WHILE i < n DO
SELECT ChanelNumber FROM SourceTable LIMIT i, 1 INTO CNumber;
SELECT StartTime FROM SourceTable LIMIT i, 1 INTO STime;
SELECT FinishTime FROM SourceTable LIMIT i, 1 INTO FTime;
SET #stat1 = CONCAT('UPDATE DestinationTable
SET ', CONCAT('Ch', CNumber), ' = 1 WHERE minutes BETWEEN ? AND ?');
PREPARE statement FROM #stat1;
SET #p1 = STime;
SET #p2 = FTime;
EXECUTE statement USING #p1, #p2;
SET i = i + 1;
END WHILE;
END$$
P.S. Don't forget to change Delimiter when create stored procedure :)
I modified the PHP code from #peter-bowers to this and got it to work:
<?php
$mysqli = new mysqli("ip", "user", "pass", "db");
if ($mysqli->connect_errno) {
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$res = $mysqli->query("update scott_test set Ch1 = null, Ch2 = null, Ch3 = null, Ch4 = null, Ch5 = null, Ch6 = null, Ch7 = null, Ch8 = null, Ch9 = null, Ch10 = null");
$res = $mysqli->query("SELECT TIMESTAMPDIFF(MINUTE,DATE(TimeReceived),TimeReceived) AS StartTime,
CEIL(FaxDuration/60)+ TIMESTAMPDIFF(MINUTE,DATE(TimeReceived),TimeReceived) AS FinishTime,
ChannelNumber
FROM
fax_received
WHERE
DATE(TimeReceived) = DATE((NOW() - INTERVAL 3 DAY))");
while ($row = $res->fetch_assoc()) {
$channel_col = 'ch'.$row['ChannelNumber'];
$start_min = $row['StartTime'];
$end_min = $row['FinishTime'];
$sql = "UPDATE scott_test
SET $channel_col = 1
WHERE minutes between ($start_min, $end_min);
$mysqli->query($sql);
}
?>

Outputted data shows each related record instead of one with no data in the last field

I'm outputting a list of cruises to show availability status, but I'm getting each cruise several times with each cabins status, I only want the cruise, then if all the cabins are sold out the outputted status should be C, otherwise A
here are my queries
<?php
$maketemp = "CREATE TEMPORARY TABLE temp (
`sailingId` varchar(5) NOT NULL,
marketCurrency varchar(3),
`Status` varchar(1)
)";
mysql_query( $maketemp, $connection ) or
die ( "Sql error : " . mysql_error ( ) );
$inserttemp = "INSERT INTO
temp
SELECT
code AS sailingId,
'USD' AS marketCurrency,
CASE
WHEN fares_usa.status = 'sold_out' THEN 'C'
END AS Status
FROM
cruises,
fares_usa
WHERE
live ='Y' AND
cruises.id = fares_usa.cruise_id";
mysql_query( $inserttemp, $connection ) or
die ( "Sql error : " . mysql_error ( ) );
$select = "SELECT sailingId, marketCurrency, Status FROM temp";
$export = mysql_query ( $select, $connection ) or
die ( "Sql error : " . mysql_error( ) );
$fields = mysql_num_fields ( $export );
So this is how I did it...
$inserttemp = "INSERT INTO temp SELECT code AS sailingId, 'USD' AS marketCurrency, CASE WHEN GROUP_CONCAT(DISTINCT status) = 'Sold Out' THEN 'C' ELSE 'A' END AS Status FROM cruises, fares_usa WHERE live ='Y' AND cruises.id = fares_usa.cruise_id GROUP BY cruises.code";
result !